Example #1
0
        public void Test20Mb()
        {
            using (var source = Create(AbstractTextLogSourceAcceptanceTest.File20Mb))
                using (var merged = new MergedLogSource(_taskScheduler, TimeSpan.FromMilliseconds(1), source))
                {
                    source.Property(x => x.GetProperty(Properties.PercentageProcessed)).ShouldAfter(TimeSpan.FromSeconds(15)).Be(Percentage.HundredPercent);
                    merged.Property(x => x.GetProperty(Properties.PercentageProcessed)).ShouldAfter(TimeSpan.FromSeconds(15)).Be(Percentage.HundredPercent);

                    merged.GetProperty(Properties.LogEntryCount).Should().Be(source.GetProperty(Properties.LogEntryCount));
                    merged.GetProperty(Properties.LogEntryCount).Should().Be(165342);
                    merged.GetProperty(Properties.Size).Should().Be(source.GetProperty(Properties.Size));
                    merged.GetProperty(Properties.StartTimestamp).Should().Be(source.GetProperty(Properties.StartTimestamp));

                    var sourceEntries = source.GetEntries(new LogSourceSection(0, source.GetProperty(Properties.LogEntryCount)));
                    var mergedEntries = merged.GetEntries(new LogSourceSection(0, merged.GetProperty(Properties.LogEntryCount)));
                    for (int i = 0; i < source.GetProperty(Properties.LogEntryCount); ++i)
                    {
                        var mergedEntry = mergedEntries[i];
                        var sourceEntry = sourceEntries[i];

                        mergedEntry.Index.Should().Be(sourceEntry.Index);
                        mergedEntry.LogEntryIndex.Should().Be(sourceEntry.LogEntryIndex);
                        mergedEntry.LineNumber.Should().Be(sourceEntry.LineNumber);
                        mergedEntry.RawContent.Should().Be(sourceEntry.RawContent);
                        mergedEntry.DeltaTime.Should().Be(sourceEntry.DeltaTime);
                        if (i > 0)
                        {
                            mergedEntry.DeltaTime.Should().BeGreaterOrEqualTo(TimeSpan.Zero);
                        }
                    }
                }
        }
Example #2
0
        public void TestMerge4()
        {
            var source1 = new InMemoryLogSource();
            var source2 = new InMemoryLogSource();
            var merged  = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source1, source2);
            var entries = Listen(merged);

            source1.AddEntry("a", LevelFlags.Warning, new DateTime(2019, 5, 28, 22, 40, 0));
            source1.AddEntry("b", LevelFlags.Info);
            source1.AddEntry("c", LevelFlags.Error, new DateTime(2019, 5, 28, 22, 41, 0));

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(2);
            entries.Count.Should().Be(2);
            entries[0].Index.Should().Be(0);
            entries[0].OriginalIndex.Should().Be(0);
            entries[0].LogEntryIndex.Should().Be(0);
            entries[0].RawContent.Should().Be("a");
            entries[0].LogLevel.Should().Be(LevelFlags.Warning);
            entries[0].Timestamp.Should().Be(new DateTime(2019, 5, 28, 22, 40, 0));
            entries[1].Index.Should().Be(1);
            entries[1].OriginalIndex.Should().Be(1);
            entries[1].LogEntryIndex.Should().Be(1);
            entries[1].RawContent.Should().Be("c");
            entries[1].LogLevel.Should().Be(LevelFlags.Error);
            entries[1].Timestamp.Should().Be(new DateTime(2019, 5, 28, 22, 41, 0));
        }
Example #3
0
        public void TestOriginalDataSourceName1()
        {
            var source1 = new InMemoryLogSource(Core.Columns.OriginalDataSourceName);
            var source2 = new InMemoryLogSource(Core.Columns.OriginalDataSourceName);
            var merged  = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source1, source2);

            source1.Add(new Dictionary <IColumnDescriptor, object>
            {
                { Core.Columns.OriginalDataSourceName, "important_document.txt" },
                { Core.Columns.Timestamp, new DateTime(2021, 02, 11, 23, 33, 10) }
            });

            source2.Add(new Dictionary <IColumnDescriptor, object>
            {
                { Core.Columns.OriginalDataSourceName, "rubbish.log" },
                { Core.Columns.Timestamp, new DateTime(2021, 02, 11, 23, 29, 10) }
            });

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(2);
            var entries = merged.GetEntries(new LogSourceSection(0, 2));

            entries[0].GetValue(Core.Columns.OriginalDataSourceName).Should().Be("rubbish.log");
            entries[0].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(1));
            entries[1].GetValue(Core.Columns.OriginalDataSourceName).Should().Be("important_document.txt");
            entries[1].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(0));

            entries = merged.GetEntries(new [] { new LogLineIndex(1), new LogLineIndex(0) });
            entries[0].GetValue(Core.Columns.OriginalDataSourceName).Should().Be("important_document.txt");
            entries[0].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(0));
            entries[1].GetValue(Core.Columns.OriginalDataSourceName).Should().Be("rubbish.log");
            entries[1].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(1));
        }
Example #4
0
        private void UpdateUnfilteredLogFile()
        {
            _logSource?.Dispose();

            OriginalSources = _dataSources.ToList();

            var logFiles = OriginalSources.Select(dataSource =>
            {
                // Unfortunately, due to a hack, the attribution to the original data source
                // will be lost if we were to not forward anything to the merged data source.
                if (Settings.ExcludedDataSources.Contains(dataSource.Id))
                {
                    return(new EmptyLogSource());
                }

                if (IsSingleLine)
                {
                    return(dataSource.OriginalLogSource);
                }

                return(dataSource.UnfilteredLogSource);
            })
                           .ToList();

            _logSource = new MergedLogSource(TaskScheduler,
                                             MaximumWaitTime,
                                             logFiles);
            _unfilteredLogSource.InnerLogSource = _logSource;
        }
Example #5
0
        public void TestGetLineNumbersByIndices()
        {
            var source1 = new InMemoryLogSource();

            source1.Add(new LogEntry {
                Timestamp = new DateTime(2017, 12, 20, 23, 1, 0)
            });

            var source2 = new InMemoryLogSource();

            source1.Add(new LogEntry {
                Timestamp = new DateTime(2017, 12, 20, 23, 0, 0)
            });

            var logFile = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source1, source2);

            _taskScheduler.RunOnce();
            logFile.GetProperty(Core.Properties.LogEntryCount).Should().Be(2);

            var lineNumbers = logFile.GetColumn(new LogLineIndex[] { 1, 0 }, Core.Columns.LineNumber);

            lineNumbers[0].Should().Be(2);
            lineNumbers[1].Should().Be(1);

            lineNumbers = logFile.GetColumn(new LogLineIndex[] { 1, 0 }, Core.Columns.OriginalLineNumber);
            lineNumbers[0].Should().Be(2);
            lineNumbers[1].Should().Be(1);
        }
Example #6
0
        public void TestMergeMultiline4()
        {
            var source = new InMemoryLogSource();
            var merged = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source);

            source.AddMultilineEntry(LevelFlags.Other, new DateTime(2017, 12, 3, 11, 59, 30), new []
            {
                "2017-12-03 11:59:30 Hello, ",
                "World!"
            });
            _taskScheduler.RunOnce();

            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(2);

            var entries = merged.GetEntries(new[] { new LogLineIndex(0), new LogLineIndex(1) },
                                            new IColumnDescriptor[]
            {
                Core.Columns.LineNumber, Core.Columns.LogEntryIndex, Core.Columns.Timestamp,
                Core.Columns.RawContent
            });
            var line = entries[0];

            line.GetValue(Core.Columns.LineNumber).Should().Be(1);
            line.GetValue(Core.Columns.LogEntryIndex).Should().Be(0);
            line.RawContent.Should().Be("2017-12-03 11:59:30 Hello, ");

            line = entries[1];
            line.GetValue(Core.Columns.LineNumber).Should().Be(2);
            line.GetValue(Core.Columns.LogEntryIndex).Should().Be(0);
            line.RawContent.Should().Be("World!");
        }
Example #7
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) });
        }
Example #8
0
        public void TestMerge3()
        {
            var source0 = new InMemoryLogSource();
            var source1 = new InMemoryLogSource();
            var merged  = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source0, source1);
            var entries = Listen(merged);

            DateTime timestamp = DateTime.Now;

            source0.AddEntry("a", LevelFlags.Info, timestamp);

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.HundredPercent);

            source1.AddEntry("b", LevelFlags.Debug, timestamp);

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.HundredPercent);
            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(2);
            entries.Count.Should().Be(2);
            entries[0].Index.Should().Be(0);
            entries[0].OriginalIndex.Should().Be(0);
            entries[0].LogEntryIndex.Should().Be(0);
            entries[0].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(0));
            entries[0].RawContent.Should().Be("a");
            entries[0].LogLevel.Should().Be(LevelFlags.Info);
            entries[0].Timestamp.Should().Be(timestamp);
            entries[1].Index.Should().Be(1);
            entries[1].OriginalIndex.Should().Be(1);
            entries[1].LogEntryIndex.Should().Be(1);
            entries[1].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(1));
            entries[1].RawContent.Should().Be("b");
            entries[1].LogLevel.Should().Be(LevelFlags.Debug);
            entries[1].Timestamp.Should().Be(timestamp);
        }
Example #9
0
        public void TestMerge5()
        {
            var source0 = new InMemoryLogSource();
            var source1 = new InMemoryLogSource();

            var merged  = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source0, source1);
            var entries = Listen(merged);

            var later   = new DateTime(2016, 2, 16);
            var earlier = new DateTime(2016, 2, 15);

            source0.AddEntry("a", LevelFlags.Warning, later);

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.HundredPercent);

            source1.AddEntry("c", LevelFlags.Error, earlier);

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.HundredPercent);
            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(2);
            entries.Count.Should().Be(2);
            entries[0].Index.Should().Be(0);
            entries[0].LogEntryIndex.Should().Be(0);
            entries[0].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(1));
            entries[0].RawContent.Should().Be("c");
            entries[0].LogLevel.Should().Be(LevelFlags.Error);
            entries[0].Timestamp.Should().Be(earlier);
            entries[1].Index.Should().Be(1);
            entries[1].LogEntryIndex.Should().Be(1);
            entries[1].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(0));
            entries[1].RawContent.Should().Be("a");
            entries[1].LogLevel.Should().Be(LevelFlags.Warning);
            entries[1].Timestamp.Should().Be(later);
        }
Example #10
0
        public void TestMerge2()
        {
            var source1 = new InMemoryLogSource();
            var source2 = new InMemoryLogSource();
            var merged  = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source1, source2);
            var entries = Listen(merged);

            source1.AddEntry("a", LevelFlags.Info, new DateTime(2019, 5, 28, 21, 59, 0));
            source1.AddEntry("b", LevelFlags.Debug, new DateTime(2019, 5, 28, 22, 0, 0));

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(2);
            entries.Count.Should().Be(2);
            entries[0].Index.Should().Be(0);
            entries[0].LogEntryIndex.Should().Be(0);
            entries[0].RawContent.Should().Be("a");
            entries[0].LogLevel.Should().Be(LevelFlags.Info);
            entries[0].Timestamp.Should().Be(new DateTime(2019, 5, 28, 21, 59, 0));
            entries[0].ElapsedTime.Should().Be(TimeSpan.Zero);
            entries[0].DeltaTime.Should().BeNull();
            entries[1].Index.Should().Be(1);
            entries[1].LogEntryIndex.Should().Be(1);
            entries[1].RawContent.Should().Be("b");
            entries[1].LogLevel.Should().Be(LevelFlags.Debug);
            entries[1].Timestamp.Should().Be(new DateTime(2019, 5, 28, 22, 0, 0));
            entries[1].ElapsedTime.Should().Be(TimeSpan.FromMinutes(1));
            entries[1].DeltaTime.Should().Be(TimeSpan.FromMinutes(1));
        }
Example #11
0
        public void TestGetTimestampsOneSource2([Range(0, 3)] int offset)
        {
            var source  = new InMemoryLogSource();
            var logFile = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source);

            source.AddEntry("", LevelFlags.Other, new DateTime(2017, 12, 14, 23, 27, 0));
            source.AddEntry("", LevelFlags.Other, new DateTime(2017, 12, 14, 23, 28, 23));
            source.AddEntry("", LevelFlags.Other, new DateTime(2017, 12, 14, 23, 29, 1));
            int count = source.Count;

            _taskScheduler.Run(2);

            var buffer = new DateTime?[offset + count];

            for (int i = 0; i < offset + count; ++i)
            {
                buffer[i] = DateTime.MinValue;
            }

            logFile.GetColumn(new LogLineIndex[] { 2, 1 }, Core.Columns.Timestamp, buffer, offset);

            for (int i = 0; i < offset; ++i)
            {
                buffer[i].Should().Be(DateTime.MinValue, "because we've specified an offset and thus values before that offset shouldn't have been touched");
            }
            buffer[offset + 0].Should().Be(source.GetEntry(2).Timestamp);
            buffer[offset + 1].Should().Be(source.GetEntry(1).Timestamp);
        }
Example #12
0
        protected override ILogSource CreateFromContent(IReadOnlyLogBuffer content)
        {
            var source = new InMemoryLogSource(content);
            var merged = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source);

            _taskScheduler.RunOnce();
            return(merged);
        }
Example #13
0
        public void TestMergeMultiline3()
        {
            var source1   = new InMemoryLogSource();
            var source1Id = new LogEntrySourceId(0);
            var source2   = new InMemoryLogSource();
            var source2Id = new LogEntrySourceId(1);
            var merged    = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source1, source2);

            var t1 = new DateTime(2017, 11, 26, 11, 45, 0);

            source1.AddEntry("Foo", LevelFlags.Info, t1);
            _taskScheduler.RunOnce();

            var t3 = new DateTime(2017, 11, 26, 11, 45, 2);

            source1.AddEntry("bar", LevelFlags.Warning, t3);
            _taskScheduler.RunOnce();

            var t2 = new DateTime(2017, 11, 26, 11, 45, 1);

            source2.AddMultilineEntry(LevelFlags.Debug, t2, "Hello,", "World!");
            _taskScheduler.RunOnce();

            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(4);
            var entries = merged.GetEntries(new LogSourceSection(0, 4));

            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(4);
            entries[0].Index.Should().Be(0);
            entries[0].LogEntryIndex.Should().Be(0);
            entries[0].GetValue(Core.Columns.SourceId).Should().Be(source1Id);
            entries[0].RawContent.Should().Be("Foo");
            entries[0].LogLevel.Should().Be(LevelFlags.Info);
            entries[0].Timestamp.Should().Be(t1);
            entries[1].Index.Should().Be(1);
            entries[1].LogEntryIndex.Should().Be(1);
            entries[1].GetValue(Core.Columns.SourceId).Should().Be(source2Id);
            entries[1].RawContent.Should().Be("Hello,");
            entries[1].LogLevel.Should().Be(LevelFlags.Debug);
            entries[1].Timestamp.Should().Be(t2);
            entries[2].Index.Should().Be(2);
            entries[2].LogEntryIndex.Should().Be(1);
            entries[2].GetValue(Core.Columns.SourceId).Should().Be(source2Id);
            entries[2].RawContent.Should().Be("World!");
            entries[2].LogLevel.Should().Be(LevelFlags.Debug);
            entries[2].Timestamp.Should().Be(t2);
            entries[3].Index.Should().Be(3);
            entries[3].LogEntryIndex.Should().Be(2);
            entries[3].GetValue(Core.Columns.SourceId).Should().Be(source1Id);
            entries[3].RawContent.Should().Be("bar");
            entries[3].LogLevel.Should().Be(LevelFlags.Warning);
            entries[3].Timestamp.Should().Be(t3);
        }
Example #14
0
        public void TestConstruction2()
        {
            var sources = Enumerable.Range(0, LogEntrySourceId.MaxSources)
                          .Select(unused =>
            {
                var logFileSource = new Mock <ILogSource>();
                logFileSource.Setup(x => x.Columns).Returns(new IColumnDescriptor[0]);
                return(logFileSource.Object);
            }).ToArray();
            var logFile = new MergedLogSource(_taskScheduler, TimeSpan.FromMilliseconds(1), sources);

            logFile.Sources.Should().Equal(sources);
        }
Example #15
0
        public void TestDispose1()
        {
            var source1 = new Mock <ILogSource>();

            source1.SetupGet(x => x.Columns).Returns(new IColumnDescriptor[0]);
            var source2 = new Mock <ILogSource>();

            source2.SetupGet(x => x.Columns).Returns(new IColumnDescriptor[0]);

            var logFile = new MergedLogSource(_taskScheduler, TimeSpan.FromMilliseconds(1), source1.Object, source2.Object);

            new Action(logFile.Dispose).Should().NotThrow();
        }
Example #16
0
        public void TestConstruction1()
        {
            var source1 = new Mock <ILogSource>();

            source1.SetupGet(x => x.Columns).Returns(new IColumnDescriptor[0]);
            var source2 = new Mock <ILogSource>();

            source2.SetupGet(x => x.Columns).Returns(new IColumnDescriptor[0]);

            MergedLogSource logSource = null;

            new Action(() => logSource = new MergedLogSource(_taskScheduler, TimeSpan.FromMilliseconds(1), source1.Object, source2.Object))
            .Should().NotThrow();
            logSource.Should().NotBeNull();
        }
Example #17
0
        public void TestManySources2()
        {
            const int sourceCount = 100;
            var       sources     = new InMemoryLogSource[sourceCount];

            for (int i = 0; i < sourceCount; ++i)
            {
                sources[i] = new InMemoryLogSource();
            }

            var merged = new MergedLogSource(_taskScheduler, TimeSpan.Zero, sources);
            var end    = new DateTime(2017, 11, 26, 17, 56, 0);

            for (int i = 0; i < sourceCount; ++i)
            {
                // Sources are modified in  reverse order: This is the worst case.
                // Reality is somewhere in between...
                sources[i].AddEntry(i.ToString(), LevelFlags.Info, end - TimeSpan.FromSeconds(i));
            }

            var changes = ListenToChanges(merged, sourceCount);

            _taskScheduler.RunOnce();

            // For once, we expect the content of the merged data source to be as expected...
            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(sourceCount, "because every source added one line");
            var entries = merged.GetEntries(new LogSourceSection(0, sourceCount));

            for (int i = 0; i < sourceCount; ++i)
            {
                var entry = entries[i];
                entry.Index.Should().Be(i);
                entry.LogEntryIndex.Should().Be(i);
                int idx = sourceCount - i - 1;
                entry.SourceId.Should().Be(new LogEntrySourceId((byte)idx));
                entry.RawContent.Should().Be(idx.ToString());
                entry.LogLevel.Should().Be(LevelFlags.Info);
                entry.Timestamp.Should().Be(end - TimeSpan.FromSeconds(idx));
            }

            // But then it should also have fired as few changes as possible!
            changes.Should().Equal(new object[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, sourceCount)
            });
        }
Example #18
0
        public void TestManySources1()
        {
            const int sourceCount = 100;
            var       sources     = new InMemoryLogSource[sourceCount];

            for (int i = 0; i < sourceCount; ++i)
            {
                sources[i] = new InMemoryLogSource();
            }

            var merged = new MergedLogSource(_taskScheduler, TimeSpan.Zero, sources);
            var start  = new DateTime(2017, 11, 26, 17, 56, 0);

            for (int i = 0; i < sourceCount; ++i)
            {
                // Sources are modified in order with perfectly ascending timestamps:
                // This is a rather unrealistic scenario...
                sources[i].AddEntry(i.ToString(), LevelFlags.Info, start + TimeSpan.FromSeconds(i));
            }

            var changes = ListenToChanges(merged, sourceCount);

            _taskScheduler.RunOnce();

            // For once, we expect the content of the merged data source to be as expected...
            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(sourceCount, "because every source added one line");

            var buffer = merged.GetEntries(new LogSourceSection(0, sourceCount));

            for (byte i = 0; i < sourceCount; ++i)
            {
                buffer[i].Index.Should().Be(i);
                buffer[i].LogEntryIndex.Should().Be(i);
                buffer[i].SourceId.Should().Be(new LogEntrySourceId(i));
                buffer[i].RawContent.Should().Be(i.ToString());
                buffer[i].LogLevel.Should().Be(LevelFlags.Info);
                buffer[i].Timestamp.Should().Be(start + TimeSpan.FromSeconds(i));
            }

            // But then it should also have fired as few changes as possible!
            changes.Should().Equal(new object[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, sourceCount)
            });
        }
Example #19
0
        public void TestGetDeltaTimesOneSource2()
        {
            var source  = new InMemoryLogSource();
            var logFile = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source);

            source.AddEntry("", LevelFlags.Other, new DateTime(2017, 12, 14, 23, 27, 0));
            source.AddEntry("", LevelFlags.Other, new DateTime(2017, 12, 14, 23, 28, 23));
            _taskScheduler.Run(2);

            var deltaTimes = logFile.GetColumn(new LogLineIndex[] { 1, 0 }, Core.Columns.DeltaTime);

            deltaTimes.Should().Equal(new object[]
            {
                TimeSpan.FromSeconds(83),
                null
            });
        }
 public void Test()
 {
     using (var source1 = Create(AbstractTextLogSourceAcceptanceTest.File2Entries))
         using (var source2 = Create(AbstractTextLogSourceAcceptanceTest.File2Lines))
         {
             var sources = new List <ILogSource> {
                 source1, source2
             };
             using (var merged = new MergedLogSource(_taskScheduler, TimeSpan.FromMilliseconds(10), sources))
             {
                 var filter = new SubstringFilter("foo", true);
                 using (var filtered = new FilteredLogSource(_taskScheduler, TimeSpan.FromMilliseconds(10), merged, null, filter))
                 {
                     filtered.Property(x => x.GetProperty(Properties.LogEntryCount)).ShouldAfter(TimeSpan.FromSeconds(5)).Be(1);
                 }
             }
         }
 }
Example #21
0
        public void TestDispose2()
        {
            var source1 = new Mock <ILogSource>();

            source1.SetupGet(x => x.Columns).Returns(new IColumnDescriptor[0]);
            var source2 = new Mock <ILogSource>();

            source2.SetupGet(x => x.Columns).Returns(new IColumnDescriptor[0]);

            var logFile = new MergedLogSource(_taskScheduler, TimeSpan.FromMilliseconds(1), source1.Object, source2.Object);

            source1.Verify(x => x.AddListener(logFile, It.IsAny <TimeSpan>(), It.IsAny <int>()), Times.Once);
            source2.Verify(x => x.AddListener(logFile, It.IsAny <TimeSpan>(), It.IsAny <int>()), Times.Once);

            logFile.Dispose();
            source1.Verify(x => x.RemoveListener(logFile), Times.Once, "because a merged log file is supposed to remove itself as a listener from its sources when its being disposed of");
            source2.Verify(x => x.RemoveListener(logFile), Times.Once, "because a merged log file is supposed to remove itself as a listener from its sources when its being disposed of");
        }
Example #22
0
        public void TestMerge1()
        {
            var source1 = new InMemoryLogSource();
            var source2 = new InMemoryLogSource();
            var merged  = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source1, source2);
            var entries = Listen(merged);

            source1.AddEntry("foobar", LevelFlags.Info, new DateTime(2019, 5, 28, 20, 31, 1));

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(1);
            entries.Count.Should().Be(1);
            entries[0].Index.Should().Be(0);
            entries[0].LogEntryIndex.Should().Be(0);
            entries[0].RawContent.Should().Be("foobar");
            entries[0].LogLevel.Should().Be(LevelFlags.Info);
            entries[0].Timestamp.Should().Be(new DateTime(2019, 5, 28, 20, 31, 1));
        }
Example #23
0
        public void TestCustomColumn()
        {
            var myCustomColumn = CreateCustomColumn <string>(null);
            var source1        = new InMemoryLogSource();

            source1.Add(new LogEntry
            {
                RawContent = "What is up Munich?",
                Timestamp  = new DateTime(2021, 02, 11, 22, 16, 49)
            });
            var source2 = new InMemoryLogSource(myCustomColumn);
            var entry2  = new LogEntry
            {
                RawContent = "Everything",
                Timestamp  = new DateTime(2021, 02, 11, 22, 15, 11)
            };

            entry2.SetValue(myCustomColumn, "A very important piece of information");
            source2.Add(entry2);

            var merged = new MergedLogSource(_taskScheduler, TimeSpan.Zero, new[] { source1, source2 });

            _taskScheduler.RunOnce();

            merged.GetProperty(Core.Properties.LogEntryCount).Should().Be(2);
            var entries = merged.GetEntries(new LogSourceSection(0, 2), new IColumnDescriptor[] { Core.Columns.RawContent, Core.Columns.Timestamp, Core.Columns.SourceId, myCustomColumn });

            entries.Count.Should().Be(2);
            entries[0].RawContent.Should().Be("Everything");
            entries[0].Timestamp.Should().Be(new DateTime(2021, 02, 11, 22, 15, 11));
            entries[0].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(1), "because this log entry is from the second source of the log file");
            entries[0].GetValue(myCustomColumn).Should().Be("A very important piece of information");
            entries[1].RawContent.Should().Be("What is up Munich?");
            entries[1].Timestamp.Should().Be(new DateTime(2021, 02, 11, 22, 16, 49));
            entries[1].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(0), "because this log entry is from the first source of the log file");
            entries[1].GetValue(myCustomColumn).Should().Be(myCustomColumn.DefaultValue, "because the first source doesn't have this column");
        }
Example #24
0
        public void TestMerge6()
        {
            var source0 = new InMemoryLogSource();
            var source1 = new InMemoryLogSource();

            var merged        = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source0, source1);
            var entries       = Listen(merged);
            var modifications = ListenToChanges(merged, 1);

            merged.OnLogFileModified(source0, LogSourceModification.Reset());
            merged.OnLogFileModified(source0, LogSourceModification.Reset());
            merged.OnLogFileModified(source0, LogSourceModification.Reset());
            merged.OnLogFileModified(source0, LogSourceModification.Reset());
            merged.OnLogFileModified(source0, LogSourceModification.Reset());
            merged.OnLogFileModified(source0, LogSourceModification.Reset());
            merged.OnLogFileModified(source1, LogSourceModification.Reset());

            DateTime timestamp = DateTime.Now;

            source1.AddEntry("Hello World", LevelFlags.Info, timestamp);

            _taskScheduler.RunOnce();
            merged.GetProperty(Core.Properties.PercentageProcessed).Should().Be(Percentage.HundredPercent);

            entries.Count.Should().Be(1);
            entries[0].Index.Should().Be(0);
            entries[0].LogEntryIndex.Should().Be(0);
            entries[0].GetValue(Core.Columns.SourceId).Should().Be(new LogEntrySourceId(1));
            entries[0].RawContent.Should().Be("Hello World");
            entries[0].LogLevel.Should().Be(LevelFlags.Info);
            entries[0].Timestamp.Should().Be(timestamp);

            int count = modifications.Count;

            modifications.ElementAt(count - 2).Should().Be(LogSourceModification.Reset());
            modifications.ElementAt(count - 1).Should().Be(LogSourceModification.Appended(0, 1));
        }
Example #25
0
        public void TestStart1()
        {
            var source = new Mock <ILogSource>();

            source.SetupGet(x => x.Columns).Returns(new IColumnDescriptor[0]);

            var listeners = new List <Tuple <ILogSourceListener, TimeSpan, int> >();

            source.Setup(x => x.AddListener(It.IsAny <ILogSourceListener>(), It.IsAny <TimeSpan>(), It.IsAny <int>()))
            .Callback(
                (ILogSourceListener listener, TimeSpan maximumWaitTime, int maximumLineCount) =>
                listeners.Add(Tuple.Create(listener, maximumWaitTime, maximumLineCount)));

            TimeSpan waitTime = TimeSpan.FromSeconds(1);
            var      logFile  = new MergedLogSource(_taskScheduler, TimeSpan.FromSeconds(1), source.Object);

            listeners.Count.Should()
            .Be(1, "Because the merged file should have registered exactly 1 listener with the source file");
            listeners[0].Item1.Should().NotBeNull();
            listeners[0].Item2.Should().Be(waitTime);
            listeners[0].Item3.Should().BeGreaterThan(0);

            GC.KeepAlive(logFile);
        }
Example #26
0
        public void Test2SmallSources()
        {
            using (var source0 = Create(AbstractTextLogSourceAcceptanceTest.File2Entries))
                using (var source1 = Create(AbstractTextLogSourceAcceptanceTest.File2Lines))
                    using (var multi0 = new MultiLineLogSource(_taskScheduler, source0, TimeSpan.Zero))
                        using (var multi1 = new MultiLineLogSource(_taskScheduler, source1, TimeSpan.Zero))
                            using (var merged = new MergedLogSource(_taskScheduler, TimeSpan.Zero, multi0, multi1))
                            {
                                source0.Property(x => x.GetProperty(Properties.PercentageProcessed)).ShouldEventually().Be(Percentage.HundredPercent);
                                source1.Property(x => x.GetProperty(Properties.PercentageProcessed)).ShouldEventually().Be(Percentage.HundredPercent);

                                multi0.Property(x => x.GetProperty(Properties.PercentageProcessed)).ShouldEventually().Be(Percentage.HundredPercent);
                                multi1.Property(x => x.GetProperty(Properties.PercentageProcessed)).ShouldEventually().Be(Percentage.HundredPercent);

                                merged.Property(x => x.GetProperty(Properties.LogEntryCount)).ShouldAfter(TimeSpan.FromSeconds(5)).Be(8, "Because the merged file should've been finished");
                                merged.Property(x => x.GetProperty(Properties.Size)).ShouldEventually().Be(source0.GetProperty(Properties.Size) + source1.GetProperty(Properties.Size));
                                merged.Property(x => x.GetProperty(Properties.StartTimestamp)).ShouldEventually().Be(source1.GetProperty(Properties.StartTimestamp));

                                var source0Lines = multi0.GetEntries(new LogSourceSection(0, source0.GetProperty(Properties.LogEntryCount)));
                                var source1Lines = multi1.GetEntries(new LogSourceSection(0, source1.GetProperty(Properties.LogEntryCount)));
                                var mergedLines  = merged.GetEntries(new LogSourceSection(0, merged.GetProperty(Properties.LogEntryCount)));

                                mergedLines[0].Index.Should().Be(0);
                                mergedLines[0].LogEntryIndex.Should().Be(0);
                                mergedLines[0].GetValue(Columns.SourceId).Should().Be(new LogEntrySourceId(1));
                                mergedLines[0].RawContent.Should().Be(source1Lines[0].RawContent);

                                mergedLines[1].Index.Should().Be(1);
                                mergedLines[1].LogEntryIndex.Should().Be(1);
                                mergedLines[1].GetValue(Columns.SourceId).Should().Be(new LogEntrySourceId(0));
                                mergedLines[1].RawContent.Should().Be(source0Lines[0].RawContent);

                                mergedLines[2].Index.Should().Be(2);
                                mergedLines[2].LogEntryIndex.Should().Be(1);
                                mergedLines[2].GetValue(Columns.SourceId).Should().Be(new LogEntrySourceId(0));
                                mergedLines[2].RawContent.Should().Be(source0Lines[1].RawContent);

                                mergedLines[3].Index.Should().Be(3);
                                mergedLines[3].LogEntryIndex.Should().Be(1);
                                mergedLines[3].GetValue(Columns.SourceId).Should().Be(new LogEntrySourceId(0));
                                mergedLines[3].RawContent.Should().Be(source0Lines[2].RawContent);

                                mergedLines[4].Index.Should().Be(4);
                                mergedLines[4].LogEntryIndex.Should().Be(2);
                                mergedLines[4].GetValue(Columns.SourceId).Should().Be(new LogEntrySourceId(1));
                                mergedLines[4].RawContent.Should().Be(source1Lines[1].RawContent);

                                mergedLines[5].Index.Should().Be(5);
                                mergedLines[5].LogEntryIndex.Should().Be(3);
                                mergedLines[5].GetValue(Columns.SourceId).Should().Be(new LogEntrySourceId(0));
                                mergedLines[5].RawContent.Should().Be(source0Lines[3].RawContent);

                                mergedLines[6].Index.Should().Be(6);
                                mergedLines[6].LogEntryIndex.Should().Be(3);
                                mergedLines[6].GetValue(Columns.SourceId).Should().Be(new LogEntrySourceId(0));
                                mergedLines[6].RawContent.Should().Be(source0Lines[4].RawContent);

                                mergedLines[7].Index.Should().Be(7);
                                mergedLines[7].LogEntryIndex.Should().Be(3);
                                mergedLines[7].GetValue(Columns.SourceId).Should().Be(new LogEntrySourceId(0));
                                mergedLines[7].RawContent.Should().Be(source0Lines[5].RawContent);
                            }
        }
Example #27
0
        public void TestMultilineNoLogLevels()
        {
            using (var source0 = Create(AbstractTextLogSourceAcceptanceTest.MultilineNoLogLevel1, new CustomTimestampParser()))
                using (var source1 = Create(AbstractTextLogSourceAcceptanceTest.MultilineNoLogLevel2, new CustomTimestampParser()))
                    using (var multi0 = new MultiLineLogSource(_taskScheduler, source0, TimeSpan.Zero))
                        using (var multi1 = new MultiLineLogSource(_taskScheduler, source1, TimeSpan.Zero))
                            using (var merged = new MergedLogSource(_taskScheduler, TimeSpan.Zero, multi0, multi1))
                            {
                                // TODO: Fix - the percentage gets reset because a log file implementation has a slightly botched Percetage calculation
                                merged.Property(x => x.GetProperty(Properties.PercentageProcessed)).ShouldAfter(TimeSpan.FromSeconds(10)).Be(Percentage.HundredPercent);

                                var entries = merged.GetEntries(new LogSourceSection(0, 11),
                                                                new IColumnDescriptor[]
                                {
                                    Columns.Timestamp,
                                    Columns.LogEntryIndex,
                                    Columns.LineNumber,
                                    Columns.RawContent,
                                    Columns.OriginalDataSourceName
                                });

                                var line = entries[0];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 176));
                                line.RawContent.Should().Be("18/03/2019 14:09:54:176    1 Information BTPVM3372 05:30:00 6060");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(0));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log2.txt");

                                line = entries[1];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 177));
                                line.RawContent.Should()
                                .Be("2019-03-18 14:09:54:177 1 00:00:00:0000000 Information Initialize Globals");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(1));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log1.txt");

                                line = entries[2];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 177));
                                line.RawContent.Should().Be("Started BTPVM3372 05:30:00 6060");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(1));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log1.txt");

                                line = entries[3];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 178));
                                line.RawContent.Should().Be("18/03/2019 14:09:54:178    1 Information   Loading preferences Started");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(2));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log2.txt");

                                line = entries[4];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 178));
                                line.RawContent.Should().Be("BTPVM3372 05:30:00 6060");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(2));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log2.txt");

                                line = entries[5];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 313));
                                line.RawContent.Should().Be("2019-03-18 14:09:54:313 1 00:00:00:0000000 Information   Loading");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(3));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log1.txt");

                                line = entries[6];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 313));
                                line.RawContent.Should().Be("preferences Started BTPVM3372 05:30:00 6060");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(3));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log1.txt");

                                line = entries[7];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 550));
                                line.RawContent.Should()
                                .Be("18/03/2019 14:09:54:550    1 Information    RMClientURL: BTPVM3372 05:30:00");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(4));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log2.txt");

                                line = entries[8];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 550));
                                line.RawContent.Should().Be("6060");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(4));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log2.txt");

                                line = entries[9];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 551));
                                line.RawContent.Should().Be("2019-03-18 14:09:54:551 1 00:00:00:0000000 Information    RMClientURL:");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(5));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log1.txt");

                                line = entries[10];
                                line.Timestamp.Should().Be(new DateTime(2019, 3, 18, 14, 9, 54, 551));
                                line.RawContent.Should().Be("BTPVM3372 05:30:00 6060");
                                line.LogEntryIndex.Should().Be(new LogEntryIndex(5));
                                line.GetValue(Columns.OriginalDataSourceName).Should().Be(@"TestData\Multiline\Log1.txt");
                            }
        }
Example #28
0
        public void TestLive1And2()
        {
            using (var source0 = Create(AbstractTextLogSourceAcceptanceTest.FileTestLive1))
                using (var source1 = Create(AbstractTextLogSourceAcceptanceTest.FileTestLive2))
                    using (var merged = new MergedLogSource(_taskScheduler, TimeSpan.Zero, source0, source1))
                    {
                        merged.Property(x => x.GetProperty(Properties.LogEntryCount)).ShouldAfter(TimeSpan.FromSeconds(5)).Be(19, "Because the merged file should've been finished");
                        merged.Property(x => x.GetProperty(Properties.Size)).ShouldEventually().Be(source0.GetProperty(Properties.Size) + source1.GetProperty(Properties.Size));
                        merged.Property(x => x.GetProperty(Properties.StartTimestamp)).ShouldEventually().Be(source0.GetProperty(Properties.StartTimestamp));

                        var entries = merged.GetEntries(new LogSourceSection(0, merged.GetProperty(Properties.LogEntryCount)));

                        entries[0].Index.Should().Be(0);
                        entries[0].LineNumber.Should().Be(1);
                        entries[0].LogEntryIndex.Should().Be(0);
                        entries[0].OriginalIndex.Should().Be(0);
                        entries[0].OriginalLineNumber.Should().Be(1);
                        entries[0].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[0].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[0].RawContent.Should().Be("2016-02-17 22:57:51,449 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Test.BusinessLogic.LogFileTest - Test");
                        entries[0].LogLevel.Should().Be(LevelFlags.Info);
                        entries[0].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 51, 449));
                        entries[0].ElapsedTime.Should().Be(TimeSpan.Zero);
                        entries[0].DeltaTime.Should().Be(null);

                        entries[1].Index.Should().Be(1);
                        entries[1].LineNumber.Should().Be(2);
                        entries[1].LogEntryIndex.Should().Be(1);
                        entries[1].OriginalIndex.Should().Be(1);
                        entries[1].OriginalLineNumber.Should().Be(2);
                        entries[1].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[1].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[1].RawContent.Should().Be("2016-02-17 22:57:51,559 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Test.BusinessLogic.LogFileTest - Hello");
                        entries[1].LogLevel.Should().Be(LevelFlags.Info);
                        entries[1].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 51, 559));
                        entries[1].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(110));
                        entries[1].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(110));

                        entries[2].Index.Should().Be(2);
                        entries[2].LineNumber.Should().Be(3);
                        entries[2].LogEntryIndex.Should().Be(2);
                        entries[2].OriginalIndex.Should().Be(2);
                        entries[2].OriginalLineNumber.Should().Be(3);
                        entries[2].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[2].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[2].RawContent.Should().Be("2016-02-17 22:57:51,560 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Test.BusinessLogic.LogFileTest - Hello");
                        entries[2].LogLevel.Should().Be(LevelFlags.Info);
                        entries[2].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 51, 560));
                        entries[2].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(111));
                        entries[2].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[3].Index.Should().Be(3);
                        entries[3].LineNumber.Should().Be(4);
                        entries[3].LogEntryIndex.Should().Be(3);
                        entries[3].OriginalIndex.Should().Be(3);
                        entries[3].OriginalLineNumber.Should().Be(4);
                        entries[3].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[3].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[3].RawContent.Should().Be("2016-02-17 22:57:51,664 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Test.BusinessLogic.LogFileTest - world!");
                        entries[3].LogLevel.Should().Be(LevelFlags.Info);
                        entries[3].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 51, 664));
                        entries[3].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(215));
                        entries[3].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(104));

                        entries[4].Index.Should().Be(4);
                        entries[4].LineNumber.Should().Be(5);
                        entries[4].LogEntryIndex.Should().Be(4);
                        entries[4].OriginalIndex.Should().Be(4);
                        entries[4].OriginalLineNumber.Should().Be(5);
                        entries[4].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[4].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[4].RawContent.Should().Be("2016-02-17 22:57:51,665 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Test.BusinessLogic.LogFileTest - world!");
                        entries[4].LogLevel.Should().Be(LevelFlags.Info);
                        entries[4].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 51, 665));
                        entries[4].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(216));
                        entries[4].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[5].Index.Should().Be(5);
                        entries[5].LineNumber.Should().Be(6);
                        entries[5].LogEntryIndex.Should().Be(5);
                        entries[5].OriginalIndex.Should().Be(5);
                        entries[5].OriginalLineNumber.Should().Be(6);
                        entries[5].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[5].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[5].RawContent.Should().Be("2016-02-17 22:57:59,284 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.Settings.DataSources - Selected item '00000000-0000-0000-0000-000000000000' not found in data-sources, ignoring it...");
                        entries[5].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[5].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 284));
                        entries[5].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7835));
                        entries[5].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(7619));

                        entries[6].Index.Should().Be(6);
                        entries[6].LineNumber.Should().Be(7);
                        entries[6].LogEntryIndex.Should().Be(6);
                        entries[6].OriginalIndex.Should().Be(6);
                        entries[6].OriginalLineNumber.Should().Be(7);
                        entries[6].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[6].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[6].RawContent.Should().Be("2016-02-17 22:57:59,285 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.Settings.DataSources - Selected item '00000000-0000-0000-0000-000000000000' not found in data-sources, ignoring it...");
                        entries[6].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[6].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 285));
                        entries[6].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7836));
                        entries[6].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[7].Index.Should().Be(7);
                        entries[7].LineNumber.Should().Be(8);
                        entries[7].LogEntryIndex.Should().Be(7);
                        entries[7].OriginalIndex.Should().Be(7);
                        entries[7].OriginalLineNumber.Should().Be(8);
                        entries[7].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[7].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[7].RawContent.Should().Be("2016-02-17 22:57:59,298 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.Settings.DataSources - Selected item '00000000-0000-0000-0000-000000000000' not found in data-sources, ignoring it...");
                        entries[7].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[7].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 298));
                        entries[7].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7849));
                        entries[7].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(13));

                        entries[8].Index.Should().Be(8);
                        entries[8].LineNumber.Should().Be(9);
                        entries[8].LogEntryIndex.Should().Be(8);
                        entries[8].OriginalIndex.Should().Be(8);
                        entries[8].OriginalLineNumber.Should().Be(9);
                        entries[8].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[8].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[8].RawContent.Should().Be("2016-02-17 22:57:59,299 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.Settings.DataSources - Selected item '00000000-0000-0000-0000-000000000000' not found in data-sources, ignoring it...");
                        entries[8].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[8].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 299));
                        entries[8].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7850));
                        entries[8].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[9].Index.Should().Be(9);
                        entries[9].LineNumber.Should().Be(10);
                        entries[9].LogEntryIndex.Should().Be(9);
                        entries[9].OriginalIndex.Should().Be(9);
                        entries[9].OriginalLineNumber.Should().Be(10);
                        entries[9].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[9].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[9].RawContent.Should().Be(@"2016-02-17 22:57:59,302 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Settings.DataSource - Data Source 'E:\Code\Tailviewer\bin\Debug\TestClear1.log' doesn't have an ID yet, setting it to: b62ea0a3-c495-4f3f-b7c7-d1a0a66e361e");
                        entries[9].LogLevel.Should().Be(LevelFlags.Info);
                        entries[9].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 302));
                        entries[9].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7853));
                        entries[9].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(3));

                        entries[10].Index.Should().Be(10);
                        entries[10].LineNumber.Should().Be(11);
                        entries[10].LogEntryIndex.Should().Be(10);
                        entries[10].OriginalIndex.Should().Be(10);
                        entries[10].OriginalLineNumber.Should().Be(11);
                        entries[10].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[10].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[10].RawContent.Should().Be(@"2016-02-17 22:57:59,303 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Settings.DataSource - Data Source 'E:\Code\Tailviewer\bin\Debug\TestClear1.log' doesn't have an ID yet, setting it to: b62ea0a3-c495-4f3f-b7c7-d1a0a66e361e");
                        entries[10].LogLevel.Should().Be(LevelFlags.Info);
                        entries[10].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 303));
                        entries[10].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7854));
                        entries[10].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[11].Index.Should().Be(11);
                        entries[11].LineNumber.Should().Be(12);
                        entries[11].LogEntryIndex.Should().Be(11);
                        entries[11].OriginalIndex.Should().Be(11);
                        entries[11].OriginalLineNumber.Should().Be(12);
                        entries[11].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[11].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[11].RawContent.Should().Be(@"2016-02-17 22:57:59,304 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Settings.DataSource - Data Source 'E:\Code\Tailviewer\bin\Debug\TestClear2.log' doesn't have an ID yet, setting it to: 0ff1c032-0754-405f-8193-2fa4dbfb7d07");
                        entries[11].LogLevel.Should().Be(LevelFlags.Info);
                        entries[11].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 304));
                        entries[11].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7855));
                        entries[11].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[12].Index.Should().Be(12);
                        entries[12].LineNumber.Should().Be(13);
                        entries[12].LogEntryIndex.Should().Be(12);
                        entries[12].OriginalIndex.Should().Be(12);
                        entries[12].OriginalLineNumber.Should().Be(13);
                        entries[12].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[12].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[12].RawContent.Should().Be(@"2016-02-17 22:57:59,305 [CurrentAppDomainHost.ExecuteNodes] INFO  Tailviewer.Settings.DataSource - Data Source 'E:\Code\Tailviewer\bin\Debug\TestClear2.log' doesn't have an ID yet, setting it to: 0ff1c032-0754-405f-8193-2fa4dbfb7d07");
                        entries[12].LogLevel.Should().Be(LevelFlags.Info);
                        entries[12].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 305));
                        entries[12].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7856));
                        entries[12].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[13].Index.Should().Be(13);
                        entries[13].LineNumber.Should().Be(14);
                        entries[13].LogEntryIndex.Should().Be(13);
                        entries[13].OriginalIndex.Should().Be(13);
                        entries[13].OriginalLineNumber.Should().Be(14);
                        entries[13].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[13].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[13].RawContent.Should().Be("2016-02-17 22:57:59,306 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.Settings.DataSources - Selected item '00000000-0000-0000-0000-000000000000' not found in data-sources, ignoring it...");
                        entries[13].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[13].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 306));
                        entries[13].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7857));
                        entries[13].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[14].Index.Should().Be(14);
                        entries[14].LineNumber.Should().Be(15);
                        entries[14].LogEntryIndex.Should().Be(14);
                        entries[14].OriginalIndex.Should().Be(14);
                        entries[14].OriginalLineNumber.Should().Be(15);
                        entries[14].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[14].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[14].RawContent.Should().Be("2016-02-17 22:57:59,307 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.Settings.DataSources - Selected item '00000000-0000-0000-0000-000000000000' not found in data-sources, ignoring it...");
                        entries[14].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[14].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 307));
                        entries[14].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7858));
                        entries[14].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[15].Index.Should().Be(15);
                        entries[15].LineNumber.Should().Be(16);
                        entries[15].LogEntryIndex.Should().Be(15);
                        entries[15].OriginalIndex.Should().Be(15);
                        entries[15].OriginalLineNumber.Should().Be(16);
                        entries[15].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[15].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[15].RawContent.Should().Be("2016-02-17 22:57:59,310 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.Settings.DataSources - Selected item '00000000-0000-0000-0000-000000000000' not found in data-sources, ignoring it...");
                        entries[15].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[15].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 310));
                        entries[15].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7861));
                        entries[15].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(3));

                        entries[16].Index.Should().Be(16);
                        entries[16].LineNumber.Should().Be(17);
                        entries[16].LogEntryIndex.Should().Be(16);
                        entries[16].OriginalIndex.Should().Be(16);
                        entries[16].OriginalLineNumber.Should().Be(17);
                        entries[16].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[16].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[16].RawContent.Should().Be("2016-02-17 22:57:59,311 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.Settings.DataSources - Selected item '00000000-0000-0000-0000-000000000000' not found in data-sources, ignoring it...");
                        entries[16].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[16].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 311));
                        entries[16].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(7862));
                        entries[16].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));

                        entries[17].Index.Should().Be(17);
                        entries[17].LineNumber.Should().Be(18);
                        entries[17].LogEntryIndex.Should().Be(17);
                        entries[17].OriginalIndex.Should().Be(17);
                        entries[17].OriginalLineNumber.Should().Be(18);
                        entries[17].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive1);
                        entries[17].SourceId.Should().Be(new LogEntrySourceId(0));
                        entries[17].RawContent.Should().Be(@"2016-02-17 22:57:59,863 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.BusinessLogic.DataSources - DataSource 'foo (ec976867-195b-4adf-a819-a1427f0d9aac)' is assigned a parent 'f671f235-7084-4e57-b06a-d253f750fae6' but we don't know that one");
                        entries[17].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[17].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 863));
                        entries[17].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(8414));
                        entries[17].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(552));

                        entries[18].Index.Should().Be(18);
                        entries[18].LineNumber.Should().Be(19);
                        entries[18].LogEntryIndex.Should().Be(18);
                        entries[18].OriginalIndex.Should().Be(18);
                        entries[18].OriginalLineNumber.Should().Be(19);
                        entries[18].OriginalDataSourceName.Should().Be(AbstractTextLogSourceAcceptanceTest.FileTestLive2);
                        entries[18].SourceId.Should().Be(new LogEntrySourceId(1));
                        entries[18].RawContent.Should().Be(@"2016-02-17 22:57:59,864 [CurrentAppDomainHost.ExecuteNodes] WARN  Tailviewer.BusinessLogic.DataSources - DataSource 'foo (ec976867-195b-4adf-a819-a1427f0d9aac)' is assigned a parent 'f671f235-7084-4e57-b06a-d253f750fae6' but we don't know that one");
                        entries[18].LogLevel.Should().Be(LevelFlags.Warning);
                        entries[18].Timestamp.Should().Be(new DateTime(2016, 2, 17, 22, 57, 59, 864));
                        entries[18].ElapsedTime.Should().Be(TimeSpan.FromMilliseconds(8415));
                        entries[18].DeltaTime.Should().Be(TimeSpan.FromMilliseconds(1));
                    }
        }