public void TestAppendTwoSourcesWrongOrderSeparateChangesPartialInvalidation()
        {
            var source1 = new InMemoryLogSource();

            source1.AddEntry("A", LevelFlags.Other, new DateTime(2019, 5, 28, 00, 34, 0));
            source1.AddEntry("C", LevelFlags.Other, new DateTime(2019, 5, 28, 00, 36, 0));
            var source2 = new InMemoryLogSource();

            source2.AddEntry("B", LevelFlags.Other, new DateTime(2019, 5, 28, 00, 35, 0));
            source2.AddEntry("D", LevelFlags.Other, new DateTime(2019, 5, 28, 00, 37, 0));

            var index   = new MergedLogSourceIndex(source1, source2);
            var changes = index.Process(new MergedLogSourcePendingModification(source1, LogSourceModification.Appended(0, 2)));

            changes.Should().Equal(new object[]
            {
                LogSourceModification.Appended(0, 2)
            });

            changes = index.Process(new MergedLogSourcePendingModification(source2, LogSourceModification.Appended(0, 2)));
            changes.Should().Equal(new object[]
            {
                LogSourceModification.Removed(1, 1),
                LogSourceModification.Appended(1, 3)
            });
        }
Beispiel #2
0
        public void TestFollowTail2()
        {
            _control.RaiseEvent(new RoutedEventArgs(FrameworkElement.LoadedEvent));
            _control.LogSource = _logSource;
            DispatcherExtensions.ExecuteAllEvents();

            var entries = new List <IReadOnlyLogEntry>();

            for (int i = 0; i < 51; ++i)
            {
                entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object>
                {
                    { Columns.RawContent, "Foobar" },
                    { Columns.LogLevel, LevelFlags.Info }
                }));
            }
            _logSource.AddRange(entries);

            Thread.Sleep((int)(2 * LogEntryListView.MaximumRefreshInterval.TotalMilliseconds));
            DispatcherExtensions.ExecuteAllEvents();


            _control.FollowTail = true;
            _logSource.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object>
            {
                { Columns.RawContent, "Foobar" },
                { Columns.LogLevel, LevelFlags.Info }
            }));
            _control.OnLogFileModified(_logSource, LogSourceModification.Appended(0, _logSource.Count));
            Thread.Sleep((int)(2 * LogEntryListView.MaximumRefreshInterval.TotalMilliseconds));
            DispatcherExtensions.ExecuteAllEvents();

            _control.VerticalScrollBar.Maximum.Should().Be(15, "Because the view is missing 15 pixels to fully display the last row");
            _control.VerticalScrollBar.Value.Should().Be(15, "Because the vertical scrollbar should've moved in order to bring the last line *fully* into view");
        }
Beispiel #3
0
        public void TestPercentageProcessed()
        {
            var source           = new Mock <ILogSource>();
            var sourceProperties = new PropertiesBufferList();

            sourceProperties.SetValue(Core.Properties.PercentageProcessed, Percentage.Zero);
            source.Setup(x => x.Columns).Returns(Core.Columns.Minimum);
            source.Setup(x => x.GetAllProperties(It.IsAny <IPropertiesBuffer>()))
            .Callback((IPropertiesBuffer destination) => sourceProperties.CopyAllValuesTo(destination));
            source.Setup(x => x.GetProperty(Core.Properties.PercentageProcessed))
            .Returns(() => sourceProperties.GetValue(Core.Properties.PercentageProcessed));
            source.Setup(x => x.Properties).Returns(() => sourceProperties.Properties);

            using (var file = Create(source.Object))
            {
                var fileListener = (ILogSourceListener)file;

                file.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.Zero, "because the filtered log file hasn't consumed anything of its source (yet)");

                _taskScheduler.RunOnce();
                file.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.Zero, "because even though the filter doesn't have anything to do just yet - it's because its own source hasn't even started");

                sourceProperties.SetValue(Core.Properties.PercentageProcessed, Percentage.FromPercent(42));
                fileListener.OnLogFileModified(source.Object, LogSourceModification.Appended(0, 84));
                _taskScheduler.RunOnce();
                file.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.FromPercent(42), "because now the filtered log file has processed 100% of the data the source sent it, but the original data source is still only at 42%");

                sourceProperties.SetValue(Core.Properties.PercentageProcessed, Percentage.HundredPercent);
                fileListener.OnLogFileModified(source.Object, LogSourceModification.Appended(84, 200));
                _taskScheduler.RunOnce();
                file.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.HundredPercent);
            }
        }
        public void TestFlush1()
        {
            var collection = new LogSourceListenerCollection(new Mock <ILogSource>().Object);

            var listener      = new Mock <ILogSourceListener>();
            var modifications = new List <LogSourceModification>();

            listener.Setup(x => x.OnLogFileModified(It.IsAny <ILogSource>(), It.IsAny <LogSourceModification>()))
            .Callback((ILogSource file, LogSourceModification y) => modifications.Add(y));

            collection.AddListener(listener.Object, TimeSpan.FromHours(1), 1000);
            collection.OnRead(1);

            modifications.Should().Equal(new object[]
            {
                LogSourceModification.Reset()
            });

            collection.Flush();
            modifications.Should().Equal(new object[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, 1)
            }, "Because Flush() should force calling the OnLogFileModified method");
        }
        public void TestPrefetchAsyncBatch()
        {
            var pageSize     = 100;
            var buffer       = new PageBufferedLogSource(_taskScheduler, _source.Object, TimeSpan.Zero, pageSize: pageSize);
            var destination  = new LogBufferArray(4, new IColumnDescriptor[] { Core.Columns.Index, Core.Columns.RawContent });
            var queryOptions = new LogSourceQueryOptions(LogSourceQueryMode.FromCache | LogSourceQueryMode.FetchForLater);

            buffer.OnLogFileModified(_source.Object, LogSourceModification.Appended(0, 10));

            var section1ToQuery = new LogSourceSection(2, 4);

            buffer.GetEntries(section1ToQuery, destination, 0, queryOptions);
            _source.Verify(x => x.GetEntries(It.IsAny <IReadOnlyList <LogLineIndex> >(), It.IsAny <ILogBuffer>(), It.IsAny <int>(), It.IsAny <LogSourceQueryOptions>()),
                           Times.Never, "Because we didn't allow data to be retrieved on the calling thread");

            var section2ToQuery = new LogSourceSection(7, 3);

            buffer.GetEntries(section2ToQuery, destination, 0, queryOptions);
            _source.Verify(x => x.GetEntries(It.IsAny <IReadOnlyList <LogLineIndex> >(), It.IsAny <ILogBuffer>(), It.IsAny <int>(), It.IsAny <LogSourceQueryOptions>()),
                           Times.Never, "Because we didn't allow data to be retrieved on the calling thread");

            _taskScheduler.RunOnce();
            _source.Verify(x => x.GetEntries(new LogSourceSection(0, pageSize), It.IsAny <ILogBuffer>(), It.IsAny <int>(), It.IsAny <LogSourceQueryOptions>()),
                           Times.Once, "Because the buffer should avoid reading the same data for the same page multiple times in a row");
        }
Beispiel #6
0
        public void TestReadOneLine4()
        {
            _streamWriter.Write("A");
            _streamWriter.Flush();
            _taskScheduler.RunOnce();

            _streamWriter.Write("B");
            _streamWriter.Flush();
            _taskScheduler.RunOnce();

            _streamWriter.Write("C");
            _streamWriter.Flush();
            _taskScheduler.RunOnce();

            _modifications.Should().Equal(new object[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, 1),
                LogSourceModification.Removed(0, 1),
                LogSourceModification.Appended(0, 1),
                LogSourceModification.Removed(0, 1),
                LogSourceModification.Appended(0, 1)
            }, "because the log file should've sent invalidations for the 2nd and 3rd read (because the same line was modified)");

            _source.GetProperty(Properties.LogEntryCount).Should().Be(1);
            var entry = _source.GetEntry(0);

            entry.Index.Should().Be(0);
            entry.LogEntryIndex.Should().Be(0);
            entry.RawContent.Should().Be("ABC");
        }
Beispiel #7
0
        public void TestDataSourceDoesntExist2()
        {
            var dataSource  = new Mock <IFileDataSource>();
            var logFile     = new Mock <ILogSource>();
            var emptyReason = new SourceDoesNotExist("E:\\Tailviewer\\somefile.log");

            logFile.Setup(x => x.GetProperty(Properties.EmptyReason)).Returns(emptyReason);
            logFile.Setup(x => x.GetProperty(Properties.Size)).Returns((Size?)null);
            var filteredLogFile         = new Mock <ILogSource>();
            ILogSourceListener listener = null;

            filteredLogFile.Setup(x => x.AddListener(It.IsAny <ILogSourceListener>(), It.IsAny <TimeSpan>(), It.IsAny <int>()))
            .Callback((ILogSourceListener l, TimeSpan t, int i) => listener = l);
            dataSource.Setup(x => x.UnfilteredLogSource).Returns(logFile.Object);
            dataSource.Setup(x => x.FullFileName).Returns(@"E:\Tailviewer\somefile.log");
            dataSource.Setup(x => x.FilteredLogSource).Returns(filteredLogFile.Object);
            dataSource.Setup(x => x.Search).Returns(new Mock <ILogSourceSearch>().Object);

            var dataSourceModel = CreateFileViewModel(dataSource.Object);
            var model           = new LogViewerViewModel(dataSourceModel, _actionCenter.Object, _settings.Object, TimeSpan.Zero);

            model.LogEntryCount.Should().Be(0);
            model.NoEntriesExplanation.Should().Be("Data source does not exist");
            model.NoEntriesAction.Should().Be("The data source 'somefile.log' was last seen E:\\Tailviewer");

            logFile.Setup(x => x.GetProperty(Properties.EmptyReason)).Returns((IEmptyReason)null);
            logFile.Setup(x => x.GetProperty(Properties.Size)).Returns(Size.Zero);
            listener.OnLogFileModified(logFile.Object, LogSourceModification.Appended(0, 0));
            model.Update();

            model.NoEntriesExplanation.Should().Be("Data source is empty");
            model.NoEntriesAction.Should().BeNull();
        }
        public void TestFilter2()
        {
            using (var file = Create(File20Mb))
            {
                file.Property(x => x.GetProperty(Properties.LogEntryCount)).ShouldAfter(TimeSpan.FromSeconds(10)).Be(165342);

                using (FilteredLogSource filtered = file.AsFiltered(_taskScheduler, null, Filter.Create("info")))
                {
                    var listener      = new Mock <ILogSourceListener>();
                    var modifications = new List <LogSourceModification>();
                    listener.Setup(x => x.OnLogFileModified(It.IsAny <ILogSource>(), It.IsAny <LogSourceModification>()))
                    .Callback((ILogSource logFile, LogSourceModification modification) => modifications.Add(modification));

                    filtered.Property(x => x.GetProperty(Properties.LogEntryCount)).ShouldAfter(TimeSpan.FromSeconds(5)).Be(5);

                    filtered.AddListener(listener.Object, TimeSpan.Zero, 1);

                    modifications.Should().Equal(new object[]
                    {
                        LogSourceModification.Reset(),
                        LogSourceModification.Appended(0, 1),
                        LogSourceModification.Appended(1, 1),
                        LogSourceModification.Appended(2, 1),
                        LogSourceModification.Appended(3, 1),
                        LogSourceModification.Appended(4, 1)
                    });
                }
            }
        }
Beispiel #9
0
        public void TestMergeResetOneSource()
        {
            var source1 = new InMemoryLogSource();

            var source2 = new InMemoryLogSource();

            var merged  = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source1, source2);
            var entries = Listen(merged);
            var changes = ListenToChanges(merged, 100);

            source2.AddEntry("a", LevelFlags.Warning, new DateTime(2021, 2, 28, 22, 15, 0));
            source1.AddEntry("b", LevelFlags.Info, new DateTime(2021, 2, 28, 22, 16, 0));
            source2.AddEntry("c", LevelFlags.Error, new DateTime(2021, 2, 28, 22, 17, 0));

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.HundredPercent);
            entries.Count.Should().Be(3);
            changes.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 3) });


            source1.Clear();
            _taskScheduler.RunOnce();
            entries.Count.Should().Be(2, "because the one entry from source should have been removed from the merged source");
            changes.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 3), LogSourceModification.Removed(1, 2), LogSourceModification.Appended(1, 1) });
        }
        public void TestAppendOneSourceThreeOneLinesOneWithoutTimestamp()
        {
            var source = new InMemoryLogSource();

            source.AddEntry("A", LevelFlags.Other, new DateTime(2019, 5, 28, 19, 30, 1));
            source.AddEntry("B", LevelFlags.Other);
            source.AddEntry("C", LevelFlags.Other, new DateTime(2019, 5, 28, 19, 30, 42));

            var index   = new MergedLogSourceIndex(source);
            var changes = index.Process(new MergedLogSourcePendingModification(source, LogSourceModification.Appended(0, 3)));

            changes.Should().Equal(new object[] { LogSourceModification.Appended(0, 2) });

            index.Count.Should().Be(2);

            var indices = index.Get(new LogSourceSection(0, 2));

            indices.Count.Should().Be(2);
            indices[0].SourceId.Should().Be(0);
            indices[0].SourceLineIndex.Should().Be(0);
            indices[0].OriginalLogEntryIndex.Should().Be(0);
            indices[0].MergedLogEntryIndex.Should().Be(0);
            indices[0].Timestamp.Should().Be(new DateTime(2019, 5, 28, 19, 30, 1));

            indices[1].SourceId.Should().Be(0);
            indices[1].SourceLineIndex.Should().Be(2);
            indices[1].OriginalLogEntryIndex.Should().Be(2);
            indices[1].MergedLogEntryIndex.Should().Be(1);
            indices[1].Timestamp.Should().Be(new DateTime(2019, 5, 28, 19, 30, 42));
        }
        public void TestClear()
        {
            var source = new InMemoryLogSource();

            source.AddEntry("A", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 053));
            source.AddEntry("B", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 100));
            source.AddEntry("C", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 100));

            var index = new MergedLogSourceIndex(source);

            index.Process(new MergedLogSourcePendingModification(source, LogSourceModification.Appended(0, 3)));

            index.Count.Should().Be(3);
            var indices = index.Get(new LogSourceSection(0, 3));

            indices[0].SourceLineIndex.Should().Be(0);
            indices[1].SourceLineIndex.Should().Be(1);
            indices[2].SourceLineIndex.Should().Be(2);

            index.Clear();
            index.Count.Should().Be(0);
            indices = index.Get(new LogSourceSection(0, 3));
            indices[0].SourceLineIndex.Should().Be(-1);
            indices[1].SourceLineIndex.Should().Be(-1);
            indices[2].SourceLineIndex.Should().Be(-1);
        }
        public void TestAppendOneSourceTwoIdenticalTimestamps()
        {
            var source = new InMemoryLogSource();

            source.AddEntry("A", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 0));
            source.AddEntry("B", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 2));
            source.AddEntry("C1", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 4));
            source.AddEntry("C2", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 4));
            source.AddEntry("D", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 6));
            source.AddEntry("E", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 8));

            var index = new MergedLogSourceIndex(source);

            index.Process(new MergedLogSourcePendingModification(source, LogSourceModification.Appended(0, 6)));

            var indices = index.Get(new LogSourceSection(0, 6));

            indices[0].SourceId.Should().Be(0);
            indices[0].SourceLineIndex.Should().Be(0);

            indices[1].SourceId.Should().Be(0);
            indices[1].SourceLineIndex.Should().Be(1);

            indices[2].SourceId.Should().Be(0);
            indices[2].SourceLineIndex.Should().Be(2);

            indices[3].SourceId.Should().Be(0);
            indices[3].SourceLineIndex.Should().Be(3);

            indices[4].SourceId.Should().Be(0);
            indices[4].SourceLineIndex.Should().Be(4);

            indices[5].SourceId.Should().Be(0);
            indices[5].SourceLineIndex.Should().Be(5);
        }
        public void TestOneSourceManySameTimestamps()
        {
            var source = new InMemoryLogSource();

            source.AddEntry("A", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 053));
            source.AddEntry("B", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 100));
            source.AddEntry("C", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 100));
            source.AddEntry("D", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 100));
            source.AddEntry("E", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 115));
            source.AddEntry("F", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 115));
            source.AddEntry("G", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 115));
            source.AddEntry("H", LevelFlags.Other, new DateTime(2017, 9, 20, 15, 09, 02, 115));

            var index = new MergedLogSourceIndex(source);

            index.Process(new MergedLogSourcePendingModification(source, LogSourceModification.Appended(0, 8)));

            var indices = index.Get(new LogSourceSection(0, 8));

            indices[0].SourceLineIndex.Should().Be(0);
            indices[1].SourceLineIndex.Should().Be(1);
            indices[2].SourceLineIndex.Should().Be(2);
            indices[3].SourceLineIndex.Should().Be(3);
            indices[4].SourceLineIndex.Should().Be(4);
            indices[5].SourceLineIndex.Should().Be(5);
            indices[6].SourceLineIndex.Should().Be(6);
            indices[7].SourceLineIndex.Should().Be(7);
        }
Beispiel #14
0
        public void TestEquality()
        {
            var appendModification        = LogSourceModification.Appended(10, 41);
            var equalAppendModification   = LogSourceModification.Appended(10, 41);
            var anotherAppendModification = LogSourceModification.Appended(9, 41);

            appendModification.Should().Be(equalAppendModification);
            equalAppendModification.Should().Be(appendModification);

            appendModification.Should().NotBe(anotherAppendModification);
            anotherAppendModification.Should().NotBe(equalAppendModification);

            var removedModification = LogSourceModification.Removed(10, 41);

            appendModification.Should().NotBe(removedModification);
            equalAppendModification.Should().NotBe(removedModification);
            anotherAppendModification.Should().NotBe(removedModification);

            var anotherRemovedModification = LogSourceModification.Removed(9, 41);

            removedModification.Should().NotBe(anotherRemovedModification);
            anotherRemovedModification.Should().NotBe(anotherAppendModification);

            appendModification.Should().NotBe(LogSourceModification.Reset());
            appendModification.Should().NotBe(LogSourceModification.PropertiesChanged());

            removedModification.Should().NotBe(LogSourceModification.Reset());
            removedModification.Should().NotBe(LogSourceModification.PropertiesChanged());
        }
        public void TestOneSourceAppendReset()
        {
            var source1 = new InMemoryLogSource();

            source1.AddEntry("A", LevelFlags.Other, new DateTime(2019, 5, 28, 00, 34, 0));

            var index   = new MergedLogSourceIndex(source1);
            var changes = index.Process(new MergedLogSourcePendingModification(source1, LogSourceModification.Appended(0, 1)));

            changes.Should().Equal(new object[]
            {
                LogSourceModification.Appended(0, 1)
            });

            changes = index.Process(new MergedLogSourcePendingModification(source1, LogSourceModification.Reset()));
            changes.Should().Equal(new object[]
            {
                LogSourceModification.Reset()
            });
            index.Count.Should().Be(0);
            index.Get(new LogSourceSection(0, 1)).Should().Equal(new object[]
            {
                MergedLogLineIndex.Invalid
            });
        }
        public void TestAppendTwoSourcesWrongOrder()
        {
            var source1 = new InMemoryLogSource();

            source1.AddEntry("B", LevelFlags.Other, new DateTime(2019, 5, 27, 23, 10, 0));
            var source2 = new InMemoryLogSource();

            source2.AddEntry("A", LevelFlags.Other, new DateTime(2019, 5, 27, 23, 09, 0));

            var index   = new MergedLogSourceIndex(source1, source2);
            var changes = index.Process(new MergedLogSourcePendingModification(source1, LogSourceModification.Appended(0, 1)),
                                        new MergedLogSourcePendingModification(source2, LogSourceModification.Appended(0, 1)));

            changes.Should().Equal(new object[]
            {
                LogSourceModification.Appended(0, 2)
            });

            var indices = index.Get(new LogSourceSection(0, 2));

            indices.Count.Should().Be(2);
            indices[0].SourceId.Should().Be(1);
            indices[0].SourceLineIndex.Should().Be(0);
            indices[0].OriginalLogEntryIndex.Should().Be(0);
            indices[0].MergedLogEntryIndex.Should().Be(0);
            indices[0].Timestamp.Should().Be(new DateTime(2019, 5, 27, 23, 9, 0));

            indices[1].SourceId.Should().Be(0);
            indices[1].SourceLineIndex.Should().Be(0);
            indices[1].OriginalLogEntryIndex.Should().Be(0);
            indices[1].MergedLogEntryIndex.Should().Be(1);
            indices[1].Timestamp.Should().Be(new DateTime(2019, 5, 27, 23, 10, 0));
        }
        public void TestClear()
        {
            var collection = new LogSourceListenerCollection(new Mock <ILogSource>().Object);

            var listener      = new Mock <ILogSourceListener>();
            var modifications = new List <LogSourceModification>();

            listener.Setup(x => x.OnLogFileModified(It.IsAny <ILogSource>(), It.IsAny <LogSourceModification>()))
            .Callback((ILogSource file, LogSourceModification y) => modifications.Add(y));

            collection.AddListener(listener.Object, TimeSpan.FromHours(1), 1000);
            collection.OnRead(1);
            collection.Flush();
            modifications.Should().Equal(new object[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, 1),
            });

            collection.Clear();
            modifications.Clear();

            collection.OnRead(2);
            collection.Flush();
            modifications.Should()
            .BeEmpty("because the collection should have removed all listeners and thus we may not have been notified anymore");
        }
Beispiel #18
0
        public void TestSplitAppendTwoParts([Values(0, 1, 99, 100)] int count)
        {
            int maxCount     = count + 1;
            var modification = LogSourceModification.Appended(new LogLineIndex(0), count);

            modification.Split(maxCount).Should().Equal(new[]
            {
                modification
            }, "because we append less than the maximum number of lines");
        }
        public void TestAppendTwice()
        {
            var changes = new MergedLogSourceChanges(101);

            changes.Append(101, 6);
            changes.Append(107, 10);
            changes.Sections.Should().Equal(new object[]
            {
                LogSourceModification.Appended(101, 16)
            });
        }
        public void TestAppendTwoSourcesInterlocked()
        {
            var source1 = new InMemoryLogSource();

            source1.AddEntry("A", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 0));
            source1.AddEntry("B", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 2));
            source1.AddEntry("C", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 4));
            source1.AddEntry("D", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 6));
            source1.AddEntry("E", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 8));
            var source2 = new InMemoryLogSource();

            source2.AddEntry("1", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 1));
            source2.AddEntry("2", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 3));
            source2.AddEntry("3", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 5));
            source2.AddEntry("4", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 7));
            source2.AddEntry("5", LevelFlags.Other, new DateTime(2019, 5, 29, 00, 11, 9));

            var index = new MergedLogSourceIndex(source1, source2);

            index.Process(new MergedLogSourcePendingModification(source1, LogSourceModification.Appended(0, 5)));
            index.Process(new MergedLogSourcePendingModification(source2, LogSourceModification.Appended(0, 5)));

            var indices = index.Get(new LogSourceSection(0, 10));

            indices[0].SourceId.Should().Be(0);
            indices[0].SourceLineIndex.Should().Be(0);

            indices[1].SourceId.Should().Be(1);
            indices[1].SourceLineIndex.Should().Be(0);

            indices[2].SourceId.Should().Be(0);
            indices[2].SourceLineIndex.Should().Be(1);

            indices[3].SourceId.Should().Be(1);
            indices[3].SourceLineIndex.Should().Be(1);

            indices[4].SourceId.Should().Be(0);
            indices[4].SourceLineIndex.Should().Be(2);

            indices[5].SourceId.Should().Be(1);
            indices[5].SourceLineIndex.Should().Be(2);

            indices[6].SourceId.Should().Be(0);
            indices[6].SourceLineIndex.Should().Be(3);

            indices[7].SourceId.Should().Be(1);
            indices[7].SourceLineIndex.Should().Be(3);

            indices[8].SourceId.Should().Be(0);
            indices[8].SourceLineIndex.Should().Be(4);

            indices[9].SourceId.Should().Be(1);
            indices[9].SourceLineIndex.Should().Be(4);
        }
        public void TestAppendGap()
        {
            var changes = new MergedLogSourceChanges(0);

            changes.Append(0, 2);
            changes.Append(1, 2);
            changes.Sections.Should().Equal(new object[]
            {
                LogSourceModification.Appended(0, 3)
            });
        }
Beispiel #22
0
        public void TestSplitAppendThreePartsPartial()
        {
            var modification = LogSourceModification.Appended(new LogLineIndex(101), 67);

            modification.Split(33).Should().Equal(new[]
            {
                LogSourceModification.Appended(101, 33),
                LogSourceModification.Appended(134, 33),
                LogSourceModification.Appended(167, 1)
            }, "because we append less than the maximum number of lines");
        }
Beispiel #23
0
        public void TestCurrentLineChanged3()
        {
            var notifier = new LogSourceListenerNotifier(_logFile.Object, _listener.Object, TimeSpan.FromHours(1), 4);

            notifier.OnRead(4);
            _modifications.Should().Equal(new[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, 4)
            });
        }
        public void TestAppendInvalidate()
        {
            var changes = new MergedLogSourceChanges(0);

            changes.Append(0, 42);
            changes.RemoveFrom(20);

            changes.Sections.Should().Equal(new object[]
            {
                LogSourceModification.Appended(0, 20)
            });
        }
        public void Append(LogLineIndex index, int count)
        {
            if (count <= 0)
            {
                return;
            }

            if (TryGetLast(out var lastSection))
            {
                if (lastSection.IsRemoved(out var removedSection))
                {
                    var gap = index - removedSection.Index;
                    if (gap >= 0)
                    {
                        _modifications.Add(LogSourceModification.Appended(removedSection.Index, count + gap));
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else if (lastSection.IsReset())
                {
                    throw new NotImplementedException();
                }
                else if (lastSection.IsAppended(out var appendedSection))
                {
                    var gap = index - (appendedSection.LastIndex + 1);
                    if (gap > 0)
                    {
                        Log.WarnFormat("Inconsistency detected: Last change affects from '{0}' to '{1}' and the next one would leave a gap because it starts at '{2}'!",
                                       appendedSection.Index, appendedSection.LastIndex, index);
                    }
                    else if (gap < 0)
                    {
                        Log.WarnFormat("Inconsistency detected: Last change affects from '{0}' to '{1}' and the next one would overlap because it starts at '{2}'!",
                                       appendedSection.Index, appendedSection.LastIndex, index);
                    }

                    _modifications[_modifications.Count - 1] = LogSourceModification.Appended(appendedSection.Index, appendedSection.Count + gap + count);
                }
            }
            else
            {
                _modifications.Add(LogSourceModification.Appended(index, count));
            }

            var last = _modifications[_modifications.Count - 1];

            last.IsAppended(out var appendedSection2);
            _count = (int)(appendedSection2.Index + appendedSection2.Count);
        }
Beispiel #26
0
        public void TestListen4()
        {
            using (var proxy = new LogSourceProxy(_taskScheduler, TimeSpan.Zero, _logFile.Object))
            {
                proxy.AddListener(_listener.Object, TimeSpan.Zero, 1000);

                new Action(() => proxy.OnLogFileModified(new Mock <ILogSource>().Object, LogSourceModification.Appended(0, 1))).Should().NotThrow();
                _modifications.Should().Equal(new[] { LogSourceModification.Reset() }, "because the OnLogFileModified shouldn't have been forwarded since it's from the wrong source");

                new Action(() => proxy.OnLogFileModified(null, LogSourceModification.Appended(0, 1))).Should().NotThrow();
                _modifications.Should().Equal(new[] { LogSourceModification.Reset() }, "because the OnLogFileModified shouldn't have been forwarded since it's from the wrong source");
            }
        }
Beispiel #27
0
        public void TestAddListener2()
        {
            var logFile = new InMemoryLogSource();

            logFile.AddEntry("Foo", LevelFlags.Other);

            logFile.AddListener(_listener.Object, TimeSpan.Zero, 1);
            _modifications.Should().Equal(new object[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, 1)
            });
        }
        public void TestInvalidateThenAppendWithGap()
        {
            var changes = new MergedLogSourceChanges(10);

            changes.RemoveFrom(5);
            changes.Append(7, 10);

            changes.Sections.Should().Equal(new object[]
            {
                LogSourceModification.Removed(5, 5),
                LogSourceModification.Appended(5, 12)
            });
        }
        public void TestAppend()
        {
            var changes = new MergedLogSourceChanges(101);

            changes.Append(101, 5);
            changes.Sections.Should().Equal(new object[]
            {
                LogSourceModification.Appended(101, 5)
            });

            changes.TryGetFirstRemovedIndex(out var index).Should().BeFalse();
            index.Should().Be(LogLineIndex.Invalid);
        }
        public void TestRead2LogEntries()
        {
            using (var file = Create(File2Entries))
            {
                var listener      = new Mock <ILogSourceListener>();
                var modifications = new List <LogSourceModification>();
                listener.Setup(x => x.OnLogFileModified(It.IsAny <ILogSource>(), It.IsAny <LogSourceModification>()))
                .Callback((ILogSource logFile, LogSourceModification modification) => modifications.Add(modification));

                file.AddListener(listener.Object, TimeSpan.Zero, 1);

                modifications.Property(x => x.Count).ShouldAfter(TimeSpan.FromSeconds(5)).Be(7);

                modifications.Should().Equal(new[]
                {
                    LogSourceModification.Reset(),
                    LogSourceModification.Appended(0, 1),
                    LogSourceModification.Appended(1, 1),
                    LogSourceModification.Appended(2, 1),
                    LogSourceModification.Appended(3, 1),
                    LogSourceModification.Appended(4, 1),
                    LogSourceModification.Appended(5, 1)
                });


                var entries = file.GetEntries(new LogSourceSection(0, 6));
                entries[0].Index.Should().Be(0);
                entries[0].LogEntryIndex.Should().Be(0);
                entries[0].RawContent.Should().Be("2015-10-07 19:50:58,982 [8092, 1] INFO  SharpRemote.Hosting.OutOfProcessSiloServer (null) - Silo Server starting, args (1): \"14056\", without custom type resolver");

                entries[1].Index.Should().Be(1);
                entries[1].LogEntryIndex.Should().Be(1);
                entries[1].RawContent.Should().Be("Foobar");

                entries[2].Index.Should().Be(2);
                entries[2].LogEntryIndex.Should().Be(2);
                entries[2].RawContent.Should().Be("Some more info");

                entries[3].Index.Should().Be(3);
                entries[3].LogEntryIndex.Should().Be(3);
                entries[3].RawContent.Should().Be("2015-10-07 19:50:58,998 [8092, 1] DEBUG SharpRemote.Hosting.OutOfProcessSiloServer (null) - Args.Length: 1");

                entries[4].Index.Should().Be(4);
                entries[4].LogEntryIndex.Should().Be(4);
                entries[4].RawContent.Should().Be("Hey look at me");

                entries[5].Index.Should().Be(5);
                entries[5].LogEntryIndex.Should().Be(5);
                entries[5].RawContent.Should().Be("dwadawdadw");
            }
        }