示例#1
0
        public void TestAppendTwoSourcesWrongOrderSeparateChangesPartialInvalidation()
        {
            var source1 = new InMemoryLogFile();

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

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

            var index   = new MergedLogFileIndex(source1, source2);
            var changes = index.Process(new MergedLogFilePendingModification(source1, new LogFileSection(0, 2)));

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

            changes = index.Process(new MergedLogFilePendingModification(source2, new LogFileSection(0, 2)));
            changes.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(1, 1),
                new LogFileSection(1, 3)
            });
        }
示例#2
0
        public void TestOneLine2()
        {
            var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero);

            logFile.AddListener(_listener.Object, TimeSpan.Zero, 10);

            _lines.Add(new LogLine(0, 0, "INFO: Hello ", LevelFlags.Info));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 1));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(1);
            _changes.Should().Equal(new object[] { LogFileSection.Reset, new LogFileSection(0, 1) });

            _lines[0] = new LogLine(0, 0, "Hello World!", LevelFlags.None);
            logFile.OnLogFileModified(_source.Object, LogFileSection.Invalidate(0, 1));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(0);

            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 1));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(1);
            _changes.Should().Equal(new object[]
            {
                LogFileSection.Reset,
                new LogFileSection(0, 1),
                LogFileSection.Invalidate(0, 1),
                new LogFileSection(0, 1)
            });

            logFile.GetLine(0).Should().Be(new LogLine(0, 0, "Hello World!", LevelFlags.None));
        }
示例#3
0
        public void TestReadOneLine4()
        {
            _streamWriter.Write("A");
            _streamWriter.Flush();
            _scheduler.RunOnce();

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

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

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

            _file.Count.Should().Be(1);
            _file.GetLine(0).Should().Be(new LogLine(0, 0, "ABC", LevelFlags.None));
        }
示例#4
0
        public void TestTwoEntries1()
        {
            var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero);

            _lines.Add(new LogLine(0, 0, "DEBUG: Starting...", LevelFlags.Debug));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 1));
            _taskScheduler.RunOnce();

            logFile.AddListener(_listener.Object, TimeSpan.Zero, 10);
            _lines.Add(new LogLine(1, 1, "INFO: hello", LevelFlags.Info));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(1, 1));
            _taskScheduler.RunOnce();
            _changes.Should().Equal(new object[]
            {
                LogFileSection.Reset,
                new LogFileSection(0, 1),
                new LogFileSection(1, 1)
            });

            _changes.Clear();
            _lines.Add(new LogLine(2, 2, "world!", LevelFlags.None));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(2, 1));
            _taskScheduler.RunOnce();
            _changes.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(1, 1),
                new LogFileSection(1, 2)
            });
        }
示例#5
0
        public void TestManyEntries4()
        {
            var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero);

            _lines.Add(new LogLine(0, 0, "Foo", LevelFlags.None));
            _lines.Add(new LogLine(1, 1, "INFO: Bar", LevelFlags.Info));

            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 2));
            _taskScheduler.RunOnce();
            logFile.GetSection(new LogFileSection(0, 2))
            .Should().Equal(new object[]
            {
                new LogLine(0, 0, "Foo", LevelFlags.None),
                new LogLine(1, 1, "INFO: Bar", LevelFlags.Info)
            });

            logFile.OnLogFileModified(_source.Object, LogFileSection.Invalidate(1, 1));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(1);

            _lines[1] = new LogLine(1, 1, "Bar", LevelFlags.None);
            _lines.Add(new LogLine(2, 2, "INFO: Sup", LevelFlags.Info));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(1, 2));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(3);
            logFile.GetSection(new LogFileSection(0, 3))
            .Should().Equal(new object[]
            {
                new LogLine(0, 0, "Foo", LevelFlags.None),
                new LogLine(1, 0, "Bar", LevelFlags.None),
                new LogLine(2, 1, "INFO: Sup", LevelFlags.Info)
            });
        }
示例#6
0
        public void TestSingleLineFilter6()
        {
            var filter = new EmptyLogLineFilter();

            using (var file = new FilteredLogFile(_taskScheduler, TimeSpan.Zero, _logFile.Object, filter, null))
            {
                _entries.Add(new LogLine(0, 0, "DEBUG: This is a test", LevelFlags.Debug));
                _entries.Add(new LogLine(1, 1, "More stuff", LevelFlags.Debug));
                _entries.Add(new LogLine(2, 2, "", LevelFlags.Debug));
                _entries.Add(new LogLine(3, 3, "And even more stuff", LevelFlags.Debug));
                _entries.Add(new LogLine(4, 4, "And even more stuff", LevelFlags.Debug));
                file.OnLogFileModified(_logFile.Object, new LogFileSection(0, 5));
                _taskScheduler.RunOnce();

                file.OnLogFileModified(_logFile.Object, LogFileSection.Invalidate(3, 2));
                _taskScheduler.RunOnce();

                file.OnLogFileModified(_logFile.Object, new LogFileSection(3, 2));
                _taskScheduler.RunOnce();

                file.Count.Should().Be(4, "because the source represents 4 lines (of which the last two changed over its lifetime)");

                const string reason = "because log entry indices are supposed to be consecutive for a data source";
                file.GetLine(0).LogEntryIndex.Should().Be(0, reason);
                file.GetLine(1).LogEntryIndex.Should().Be(1, reason);
                file.GetLine(2).LogEntryIndex.Should().Be(2, reason);
                file.GetLine(3).LogEntryIndex.Should().Be(3, reason);
            }
        }
示例#7
0
        public void TestManyEntries7()
        {
            var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero);

            logFile.AddListener(_listener.Object, TimeSpan.Zero, 3);

            _lines.Add(new LogLine(0, 0, "A", LevelFlags.None));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 1));
            _taskScheduler.RunOnce();

            _lines.Add(new LogLine(1, 1, "B", LevelFlags.Info));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(1, 1));
            _taskScheduler.RunOnce();

            _lines[1] = new LogLine(1, 1, "B", LevelFlags.None);
            _lines.Add(new LogLine(2, 2, "C", LevelFlags.None));
            logFile.OnLogFileModified(_source.Object, LogFileSection.Invalidate(1, 1));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(1, 2));
            _taskScheduler.RunOnce();

            logFile.GetSection(new LogFileSection(0, 3))
            .Should().Equal(
                new LogLine(0, 0, "A", LevelFlags.None),
                new LogLine(1, 1, "B", LevelFlags.None),
                new LogLine(2, 2, "C", LevelFlags.None));
        }
示例#8
0
        public void TestSplitInvalidateGreaterThanThreshold([Values(2, 99, 100)] int count)
        {
            int maxCount = count - 1;
            var section  = LogFileSection.Invalidate(new LogLineIndex(42), count);

            section.Split(maxCount).Should().Equal(new[]
            {
                section
            }, "because invalidations are NEVER split up");
        }
        public void TestInvalidateThenAppendWithGap()
        {
            var changes = new MergedLogFileChanges(10);

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

            changes.Sections.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(5, 5),
                new LogFileSection(5, 12)
            });
        }
        public void TestInvalidate1()
        {
            var notifier = new LogFileListenerNotifier(_logFile.Object, _listener.Object, TimeSpan.Zero, 1);

            notifier.OnRead(1);
            notifier.Invalidate(0, 1);
            _changes.Should().Equal(new[]
            {
                LogFileSection.Reset,
                new LogFileSection(0, 1),
                LogFileSection.Invalidate(0, 1)
            });
            notifier.LastNumberOfLines.Should().Be(0);
        }
        public void TestInvalidate()
        {
            var changes = new MergedLogFileChanges(42);

            changes.InvalidateFrom(10);

            changes.Sections.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(10, 32)
            });

            changes.TryGetFirstInvalidationIndex(out var index).Should().BeTrue();
            index.Should().Be(new LogLineIndex(10));
        }
        public void TestInvalidateTwiceSuperfluous()
        {
            var changes = new MergedLogFileChanges(13);

            changes.InvalidateFrom(5);
            changes.InvalidateFrom(7);

            changes.Sections.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(5, 8)
            });

            changes.TryGetFirstInvalidationIndex(out var index).Should().BeTrue();
            index.Should().Be(new LogLineIndex(5));
        }
        public void Invalidate(int firstIndex, int count)
        {
            int lastIndex       = Math.Min(firstIndex + count, _lastNumberOfLines);
            int invalidateCount = lastIndex - firstIndex;

            // When the start index of the invalidation is greater than the last reported index
            // then this means that our listeners haven't even gotten the change yet and thus
            // they don't need to be notified of the invalidation either.
            if (invalidateCount > 0)
            {
                var section = LogFileSection.Invalidate(firstIndex, invalidateCount);
                _listener.OnLogFileModified(_logFile, section);
                _lastNumberOfLines = firstIndex;
            }
        }
        public void TestInvalidateThenAppend()
        {
            var changes = new MergedLogFileChanges(10);

            changes.InvalidateFrom(5);
            changes.Append(5, 6);

            changes.Sections.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(5, 5),
                new LogFileSection(5, 6)
            });

            changes.TryGetFirstInvalidationIndex(out var index).Should().BeTrue();
            index.Should().Be(new LogLineIndex(5));
        }
        public void TestInvalidate2()
        {
            var notifier = new LogFileListenerNotifier(_logFile.Object, _listener.Object, TimeSpan.FromSeconds(1), 10);

            notifier.OnRead(10);
            notifier.OnRead(12);
            notifier.Invalidate(0, 12);
            _changes.Should().Equal(new[]
            {
                LogFileSection.Reset,
                new LogFileSection(0, 10),
                LogFileSection.Invalidate(0, 10)
            },
                                    "Because the notifier should've reported only the first 10 changes and therefore Invalidate() only had to invalidate those 10 changes"
                                    );
            notifier.LastNumberOfLines.Should().Be(0);
        }
示例#16
0
        public void InvalidateFrom(LogLineIndex firstInvalidIndex)
        {
            if (firstInvalidIndex >= _count)
            {
                Log.WarnFormat("Ignoring invalidation from index '{0}' onwards because nothing has been appended there!", firstInvalidIndex);
                return;
            }

            if (firstInvalidIndex >= _initialCount)
            {
                // We do not need to add an invalidation, rather we can simply clamp an existing previous append
                if (firstInvalidIndex > 0)
                {
                    var previous = _changes[_changes.Count - 1];
                    if (!previous.IsInvalidate && !previous.IsReset)
                    {
                        var gap = previous.Index + previous.Count - firstInvalidIndex;
                        if (gap > 0)
                        {
                            previous.Count -= gap;
                            _changes[_changes.Count - 1] = previous;
                        }
                    }
                }
            }
            else
            {
                var invalidationCount = _count - firstInvalidIndex;
                if (_invalidationIndex != -1)
                {
                    var invalidation = _changes[_invalidationIndex];
                    if (invalidation.Index <= firstInvalidIndex)
                    {
                        return;                         //< Nothing to do
                    }
                    _changes[_invalidationIndex] = LogFileSection.Invalidate(firstInvalidIndex, invalidationCount);
                }
                else
                {
                    _invalidationIndex = _changes.Count;
                    _changes.Add(LogFileSection.Invalidate(firstInvalidIndex, invalidationCount));
                }
            }
        }
示例#17
0
        public void TestOneLine1()
        {
            var logFile = new MultiLineLogFile(_taskScheduler, _source.Object, TimeSpan.Zero);

            _lines.Add(new LogLine(0, 0, "INFO: Hello ", LevelFlags.Info));
            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 1));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(1);
            logFile.GetLine(0).Should().Be(new LogLine(0, 0, "INFO: Hello ", LevelFlags.Info));

            _lines[0] = new LogLine(0, 0, "INFO: Hello World!", LevelFlags.Info);
            logFile.OnLogFileModified(_source.Object, LogFileSection.Invalidate(0, 1));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(0);

            logFile.OnLogFileModified(_source.Object, new LogFileSection(0, 1));
            _taskScheduler.RunOnce();
            logFile.Count.Should().Be(1);
            logFile.GetLine(0).Should().Be(new LogLine(0, 0, "INFO: Hello World!", LevelFlags.Info));
        }
示例#18
0
        public void TestListen3()
        {
            using (var proxy = new LogFileProxy(_scheduler, TimeSpan.Zero, _logFile.Object))
            {
                proxy.AddListener(_listener.Object, TimeSpan.Zero, 1000);

                _listeners.OnRead(500);
                _listeners.Invalidate(400, 100);
                _listeners.OnRead(550);

                _scheduler.RunOnce();

                _modifications.Should().Equal(new[]
                {
                    LogFileSection.Reset,
                    new LogFileSection(0, 500),
                    LogFileSection.Invalidate(400, 100),
                    new LogFileSection(400, 150)
                });
            }
        }
示例#19
0
        public void TestInvalidate2()
        {
            using (var file = new FilteredLogFile(_taskScheduler, TimeSpan.Zero, _logFile.Object, null, Filter.Create(null, true, LevelFlags.Info)))
            {
                file.AddListener(_listener.Object, TimeSpan.Zero, 1);

                _taskScheduler.RunOnce();
                file.EndOfSourceReached.Should().BeTrue();

                _entries.AddRange(new[]
                {
                    new LogLine(0, 0, "A", LevelFlags.Info),
                    new LogLine(1, 1, "B", LevelFlags.Info),
                    new LogLine(2, 2, "C", LevelFlags.Info),
                    new LogLine(3, 3, "D", LevelFlags.Info)
                });
                file.OnLogFileModified(_logFile.Object, new LogFileSection(0, 4));

                _taskScheduler.RunOnce();
                file.EndOfSourceReached.Should().BeTrue();
                file.Count.Should().Be(4);

                file.OnLogFileModified(_logFile.Object, LogFileSection.Invalidate(2, 2));

                _taskScheduler.RunOnce();
                file.EndOfSourceReached.Should().BeTrue();
                file.Count.Should().Be(2);

                _sections.Should().Equal(new[]
                {
                    LogFileSection.Reset,
                    new LogFileSection(0, 1),
                    new LogFileSection(1, 1),
                    new LogFileSection(2, 1),
                    new LogFileSection(3, 1),
                    LogFileSection.Invalidate(2, 2)
                });
            }
        }
示例#20
0
        public void TestAppendTwoSourcesWrongOrderSeparateChangesFullInvalidation()
        {
            var source1 = new InMemoryLogFile();

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

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

            var index   = new MergedLogFileIndex(source1, source2);
            var changes = index.Process(new MergedLogFilePendingModification(source1, new LogFileSection(0, 1)));

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

            changes = index.Process(new MergedLogFilePendingModification(source2, new LogFileSection(0, 1)));
            changes.Should().Equal(new object[]
            {
                LogFileSection.Invalidate(0, 1),
                new LogFileSection(0, 2)
            });

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

            indices.Count.Should().Be(2);
            indices[0].LogFileIndex.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].LogFileIndex.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));
        }
示例#21
0
        public void TestInvalidate1()
        {
            using (var file = new FilteredLogFile(_taskScheduler, TimeSpan.Zero, _logFile.Object, null, Filter.Create(null, true, LevelFlags.Info)))
            {
                _taskScheduler.RunOnce();
                file.EndOfSourceReached.Should().BeTrue();

                _entries.AddRange(new[]
                {
                    new LogLine(0, 0, "A", LevelFlags.Info),
                    new LogLine(1, 1, "B", LevelFlags.Info),
                    new LogLine(2, 2, "C", LevelFlags.Info),
                    new LogLine(3, 3, "D", LevelFlags.Info)
                });

                file.OnLogFileModified(_logFile.Object, new LogFileSection(0, 4));
                file.OnLogFileModified(_logFile.Object, LogFileSection.Invalidate(2, 2));

                _taskScheduler.RunOnce();

                file.EndOfSourceReached.Should().BeTrue();
                file.Count.Should().Be(2, "because we've invalidated the last 2 out of 4 lines");
            }
        }
示例#22
0
 public void TestToString()
 {
     LogFileSection.Reset.ToString().Should().Be("Reset");
     LogFileSection.Invalidate(42, 5).ToString().Should().Be("Invalidated [#42, #5]");
 }