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 TestTail_WriteOneLineTwoFlushes_Changes3()
        {
            var encoding = Encoding.UTF8;
            var fileName = GetUniqueNonExistingFileName();

            var linePart1 = "The sky";
            var linePart2 = " Crawlers";

            using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read))
                using (var writer = new StreamWriter(stream, encoding))
                    using (var logFile = Create(fileName, encoding))
                    {
                        var changes = AddListener(logFile, 1000);
                        changes.Should().Equal(new object[] { LogSourceModification.Reset() });

                        writer.Write(linePart1);
                        writer.Flush();
                        _taskScheduler.RunOnce();

                        changes.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 1) },
                                               "because the file consists of one line");

                        writer.Write(linePart2);
                        writer.Flush();
                        _taskScheduler.RunOnce();

                        changes.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 1), LogSourceModification.Removed(0, 1), LogSourceModification.Appended(0, 1) });
                    }
        }
示例#3
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");
        }
        public void TestTail_WriteTwoLines_Changes1()
        {
            var encoding = Encoding.UTF8;
            var fileName = GetUniqueNonExistingFileName();

            var line1 = "The sky crawlers";
            var line2 = "is awesome!";

            using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read))
                using (var writer = new StreamWriter(stream, encoding))
                    using (var logFile = Create(fileName, encoding))
                    {
                        var changes = AddListener(logFile, 1000);
                        changes.Should().Equal(new object[] { LogSourceModification.Reset() });

                        writer.Write(line1 + "\r\n");
                        writer.Flush();
                        _taskScheduler.RunOnce();

                        changes.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 1), LogSourceModification.Appended(1, 1) },
                                               "because the file consists of two lines, one being totally empty");

                        writer.Write(line2 + "\r\n");
                        writer.Flush();
                        _taskScheduler.RunOnce();

                        changes.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 1), LogSourceModification.Appended(1, 1), LogSourceModification.Removed(1, 1), LogSourceModification.Appended(1, 2) });
                    }
        }
        public void TestTail_WriteTwoLines_Changes2()
        {
            var encoding = Encoding.UTF8;
            var fileName = GetUniqueNonExistingFileName();

            var line1 = "The sky crawlers";
            var line2 = "is awesome!";

            using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read))
                using (var writer = new StreamWriter(stream, encoding))
                    using (var logFile = Create(fileName, encoding))
                    {
                        var changes = AddListener(logFile, 1000);
                        changes.Should().Equal(new object[] { LogSourceModification.Reset() });

                        writer.Write(line1);
                        writer.Flush();
                        _taskScheduler.RunOnce();

                        changes.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 1) },
                                               "because the file consists of one line");

                        writer.Write("\n" + line2);
                        writer.Flush();
                        _taskScheduler.RunOnce();

                        //changes.Should().Equal(new object[] {LogSourceModification.Reset(), new LogFileSection(0, 1), new LogFileSection(1, 1)});
                        // The current behavior won't cause wrong behavior in upstream listeners, but it will cause them unnecessary work.
                        changes.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 1),
                                                              LogSourceModification.Removed(0, 1), LogSourceModification.Appended(0, 2) });
                    }
        }
        public void TestInvokeListenerEventually()
        {
            var line     = "Hello, World!";
            var fileName = GetUniqueNonExistingFileName();

            using (var stream = File.OpenWrite(fileName))
                using (var writer = new StreamWriter(stream))
                {
                    writer.Write(line);
                }

            var logFile       = Create(fileName, new UTF8Encoding(true));
            var listener      = new Mock <ILogSourceListener>();
            var modifications = new List <LogSourceModification>();

            listener.Setup(x => x.OnLogFileModified(logFile, It.IsAny <LogSourceModification>()))
            .Callback((ILogSource _, LogSourceModification modification) =>
            {
                modifications.Add(modification);
            });
            var maxWaitTime = TimeSpan.FromMilliseconds(500);

            logFile.AddListener(listener.Object, maxWaitTime, 500);
            modifications.Should().Equal(new object[] { LogSourceModification.Reset() });

            _taskScheduler.RunOnce();
            logFile.GetProperty(Properties.LogEntryCount).Should().Be(1, "because there's one log entry in the file");
            modifications.Should().Equal(new object[] { LogSourceModification.Reset() }, "because not enough time has elapsed and thus the log source may not have notified the listener just yet");


            Thread.Sleep(maxWaitTime);
            _taskScheduler.RunOnce();
            logFile.GetProperty(Properties.LogEntryCount).Should().Be(1, "because there's still one log entry in the file");
            modifications.Should().Equal(new object[] { LogSourceModification.Reset(), LogSourceModification.Appended(0, 1) }, "because enough time has passed for the log file to notify us at this point in time");
        }
示例#7
0
 public void AddListener(ILogSourceListener listener, TimeSpan maximumWaitTime, int maximumLineCount)
 {
     if (_listeners.Add(listener))
     {
         listener.OnLogFileModified(this, LogSourceModification.Reset());
     }
 }
        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)
                    });
                }
            }
        }
        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");
        }
示例#10
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 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
            });
        }
示例#12
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 TestClear2()
        {
            const string fname = "TestClear2.log";

            using (FileStream stream = File.OpenWrite(fname))
                using (var writer = new StreamWriter(stream))
                {
                    stream.SetLength(0);
                    writer.WriteLine("Test");
                }

            using (var logFile = Create(fname))
            {
                var listener      = new Mock <ILogSourceListener>();
                var modifications = new List <LogSourceModification>();
                listener.Setup(x => x.OnLogFileModified(It.IsAny <ILogSource>(), It.IsAny <LogSourceModification>()))
                .Callback((ILogSource log, LogSourceModification modification) => modifications.Add(modification));
                logFile.AddListener(listener.Object, TimeSpan.Zero, 2);

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

                using (var stream = new FileStream(fname, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
                {
                    stream.SetLength(0);

                    logFile.Property(x => x.GetProperty(Properties.LogEntryCount)).ShouldAfter(TimeSpan.FromSeconds(5)).Be(0);
                    modifications.Should().EndWith(LogSourceModification.Reset());
                }
            }
        }
示例#14
0
        public void TestAddListener1()
        {
            var logFile = new InMemoryLogSource();

            logFile.AddListener(_listener.Object, TimeSpan.Zero, 1);
            _modifications.Should().Equal(new object[] { LogSourceModification.Reset() });
        }
示例#15
0
        public void TestAddListener()
        {
            var logFile  = new EmptyLogSource();
            var listener = new Mock <ILogSourceListener>();

            logFile.AddListener(listener.Object, TimeSpan.Zero, 0);
            listener.Verify(x => x.OnLogFileModified(logFile, LogSourceModification.Reset()), Times.Once);
        }
示例#16
0
        public void TestSplitReset([Values(1, 99, 100)] int maxCount)
        {
            var section = LogSourceModification.Reset();

            section.Split(maxCount).Should().Equal(new[]
            {
                section
            }, "because resets are NEVER split up");
        }
示例#17
0
        public void TestCurrentLineChanged6()
        {
            var notifier = new LogSourceListenerNotifier(_logFile.Object, _listener.Object, TimeSpan.FromHours(1), 1000);

            notifier.OnRead(-1);
            _modifications.Should().Equal(new[]
            {
                LogSourceModification.Reset()
            });
        }
示例#18
0
        public LogSourceListenerNotifier(ILogSource logSource, ILogSourceListener listener, TimeSpan maximumTime, int maximumCount)
        {
            _logSource    = logSource ?? throw new ArgumentNullException(nameof(logSource));
            _listener     = listener ?? throw new ArgumentNullException(nameof(listener));
            _maximumTime  = maximumTime;
            _maximumCount = maximumCount;

            Reset();

            _listener.OnLogFileModified(logSource, LogSourceModification.Reset());
        }
示例#19
0
        public void TestClear4()
        {
            var logFile = new InMemoryLogSource();

            logFile.AddEntry("Hi", LevelFlags.Info);
            logFile.GetProperty(TextProperties.MaxCharactersInLine).Should().Be(2);

            logFile.AddListener(_listener.Object, TimeSpan.Zero, 1);
            logFile.Clear();
            _modifications.Should().EndWith(LogSourceModification.Reset());
        }
示例#20
0
        public void TestInvalidate5()
        {
            var notifier = new LogSourceListenerNotifier(_logFile.Object, _listener.Object, TimeSpan.FromMilliseconds(100), 100);

            notifier.OnRead(1);
            notifier.OnRead(-1);
            _modifications.Should().Equal(new[] { LogSourceModification.Reset() });
            notifier.OnRead(-1);
            _modifications.Should().Equal(new[] { LogSourceModification.Reset() });
            notifier.OnRead(-1);
            _modifications.Should().Equal(new[] { LogSourceModification.Reset() });
        }
示例#21
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)
            });
        }
示例#22
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");
            }
        }
        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");
            }
        }
        public void TestOptimizeOneSourceAppendReset()
        {
            var source = new Mock <ILogSource>();
            var input  = new[]
            {
                new MergedLogSourcePendingModification(source.Object, LogSourceModification.Appended(1, 2)),
                new MergedLogSourcePendingModification(source.Object, LogSourceModification.Reset())
            };

            MergedLogSourcePendingModification.Optimize(input).Should().Equal(new object[]
            {
                new MergedLogSourcePendingModification(source.Object, LogSourceModification.Reset())
            });
        }
示例#25
0
        public void TestInvalidate1()
        {
            var notifier = new LogSourceListenerNotifier(_logFile.Object, _listener.Object, TimeSpan.Zero, 1);

            notifier.OnRead(1);
            notifier.Remove(0, 1);
            _modifications.Should().Equal(new[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, 1),
                LogSourceModification.Removed(0, 1)
            });
            notifier.LastNumberOfLines.Should().Be(0);
        }
        public void TestTail_WriteLinesClearWriteLines()
        {
            var encoding = new UTF8Encoding(false);
            var fileName = GetUniqueNonExistingFileName();

            using (var logFile = Create(fileName, encoding))
            {
                var line1 = "The sky";
                var line2 = "Crawlers";
                using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read))
                    using (var writer = new StreamWriter(stream, encoding))
                    {
                        var changes = AddListener(logFile, 1000);
                        changes.Should().Equal(new object[] { LogSourceModification.Reset() });

                        writer.WriteLine(line1);
                        writer.Flush();
                        _taskScheduler.RunOnce();
                        logFile.GetProperty(Properties.LogEntryCount).Should().Be(2);
                        var index = logFile.GetColumn(new LogSourceSection(0, 2), StreamingTextLogSource.LineOffsetInBytes);
                        index[0].Should().Be(0);
                        index[1].Should().Be(9);

                        writer.WriteLine(line2);
                        writer.Flush();
                        _taskScheduler.RunOnce();
                        logFile.GetProperty(Properties.LogEntryCount).Should().Be(3);
                        index = logFile.GetColumn(new LogSourceSection(0, 3), StreamingTextLogSource.LineOffsetInBytes);
                        index[0].Should().Be(0);
                        index[1].Should().Be(9);
                        index[2].Should().Be(19);
                    }

                using (var stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read))
                    using (var writer = new StreamWriter(stream, encoding))
                    {
                        writer.WriteLine("A");
                        writer.WriteLine("B");
                        writer.Flush();

                        _taskScheduler.RunOnce();
                        logFile.GetProperty(Properties.LogEntryCount).Should().Be(3);
                        var index = logFile.GetColumn(new LogSourceSection(0, 3), StreamingTextLogSource.LineOffsetInBytes);
                        index[0].Should().Be(0);
                        index[1].Should().Be(3);
                        index[2].Should().Be(6);
                    }
            }
        }
示例#27
0
        public void TestListen1()
        {
            using (var proxy = new LogSourceProxy(_taskScheduler, TimeSpan.Zero, _logFile.Object))
            {
                proxy.AddListener(_listener.Object, TimeSpan.FromSeconds(1), 1000);
                proxy.OnLogFileModified(_logFile.Object, LogSourceModification.Appended(0, 1));

                _modifications.Property(x => x.Count).ShouldEventually().Be(2);
                _modifications.Should().Equal(new[]
                {
                    LogSourceModification.Reset(),
                    LogSourceModification.Appended(0, 1)
                });
            }
        }
示例#28
0
        public void TestReset()
        {
            var modification = LogSourceModification.Reset();

            modification.IsReset().Should().BeTrue();
            modification.ToString().Should().Be("Reset");

            modification.IsRemoved(out var removedSection).Should().BeFalse();
            removedSection.Should().Equal(new LogSourceSection());

            modification.IsAppended(out var appendedSection).Should().BeFalse();
            appendedSection.Should().Equal(new LogSourceSection());


            modification.IsPropertiesChanged().Should().BeFalse();
        }
示例#29
0
        public void TestAddMultilineEntry4()
        {
            var logFile = new InMemoryLogSource();

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

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

            logFile.AddMultilineEntry(LevelFlags.Info, t1, "foo", "bar");

            _modifications.Should().Equal(new object[]
            {
                LogSourceModification.Reset(),
                LogSourceModification.Appended(0, 2)
            });
        }
示例#30
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)
            });
        }