public PresentationLogSource(ITaskScheduler scheduler, ILogSource source, TimeSpan maximumWaitTime, TextSettings textSettings) : base(scheduler) { if (scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (source == null) { throw new ArgumentNullException(nameof(source)); } _maximumWaitTime = maximumWaitTime; _textSettings = textSettings; _source = source; _indices = new LogBufferList(IndexedColumns); _array = new LogBufferArray(MaximumLineCount, Core.Columns.RawContent); _pendingModifications = new ConcurrentQueue <PendingModification>(); _syncRoot = new object(); _source.AddListener(this, _maximumWaitTime, MaximumLineCount); StartTask(); }
public void TestRetrieveFromPartiallyFilledPage_CreatedBeforeResize() { var buffer = new PagedLogBuffer(10, 1, Core.Columns.RawContent); buffer.ResizeTo(2); var data = new LogBufferList(Core.Columns.RawContent) { new LogEntry { RawContent = "A" }, new LogEntry { RawContent = "B" } }; buffer.TryAdd(new LogSourceSection(0, 2), data, 0); buffer.ResizeTo(4); var destination = new LogBufferArray(6, PageBufferedLogSource.RetrievalState, Core.Columns.RawContent); buffer.TryGetEntries(new LogSourceSection(0, 6), destination, 0).Should().BeFalse("because the cache is only partially filled"); destination[0].GetValue(PageBufferedLogSource.RetrievalState).Should().Be(RetrievalState.Retrieved); destination[1].GetValue(PageBufferedLogSource.RetrievalState).Should().Be(RetrievalState.Retrieved); destination[2].GetValue(PageBufferedLogSource.RetrievalState).Should().Be(RetrievalState.NotCached); destination[3].GetValue(PageBufferedLogSource.RetrievalState).Should().Be(RetrievalState.NotCached); destination[4].GetValue(PageBufferedLogSource.RetrievalState).Should().Be(RetrievalState.NotInSource); destination[5].GetValue(PageBufferedLogSource.RetrievalState).Should().Be(RetrievalState.NotInSource); }
private static ILogBuffer Listen(ILogSource logSource) { var data = new LogBufferList(logSource.Columns); var listener = new Mock <ILogSourceListener>(); listener.Setup(x => x.OnLogFileModified(It.IsAny <ILogSource>(), It.IsAny <LogSourceModification>())) .Callback((ILogSource file, LogSourceModification modification) => { if (modification.IsReset()) { data.Clear(); } else if (modification.IsRemoved(out var removedSection)) { data.RemoveRange((int)removedSection.Index, removedSection.Count); } else if (modification.IsAppended(out var appendedSection)) { var destinationIndex = data.Count; data.Resize(data.Count + appendedSection.Count); file.GetEntries(appendedSection, data, destinationIndex); } }); logSource.AddListener(listener.Object, TimeSpan.Zero, 1); return(data); }
public void TestCopyFrom_Buffer_NullColumn() { var offset = 5; var count = 3; var surplus = 5; var originalBuffer = new int[offset + count + surplus]; var buffer = new int[offset + count + surplus]; for (int i = 0; i < offset + count + surplus; ++i) { originalBuffer[i] = buffer[i] = i + 1; } var view = new SingleColumnLogBufferView <int>(Core.Columns.LineNumber, buffer, offset, count); var source = new LogBufferList(Core.Columns.OriginalLineNumber, Core.Columns.LineNumber); source.Add(new LogEntry { OriginalLineNumber = 10, LineNumber = 42 }); source.Add(new LogEntry { OriginalLineNumber = 12, LineNumber = 9001 }); new Action(() => view.CopyFrom(null, 1, source, new[] { 1, 0 })) .Should().Throw <ArgumentNullException>(); for (int i = 0; i < offset + count + surplus; ++i) { buffer[i].Should().Be(originalBuffer[i], "because the buffer may not have been overwritten"); } }
public void TestFill_NullColumn() { var buffer = new LogBufferList(Core.Columns.LineNumber); buffer.Resize(10); new Action(() => buffer.Fill(null, 42, 2, 4)).Should().Throw <ArgumentNullException>(); }
public void TestCopyFromArray_PartiallyFilled() { var entries = new LogBufferList(Core.Columns.LogLevel); entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> { { Core.Columns.LogLevel, LevelFlags.Info } })); entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> { { Core.Columns.LogLevel, LevelFlags.Trace } })); var buffer = new LevelFlags[] { LevelFlags.All, LevelFlags.Debug, LevelFlags.Error, LevelFlags.Warning }; entries.Resize(4); entries.Count.Should().Be(buffer.Length); entries.CopyFrom(Core.Columns.LogLevel, 0, buffer, 0, buffer.Length); entries[0].LogLevel.Should().Be(LevelFlags.All, "because the first entry's level should have been overwritten"); entries[1].LogLevel.Should().Be(LevelFlags.Debug, "because the second entry's level should have been overwritten"); entries[2].LogLevel.Should().Be(LevelFlags.Error, "because the third log entry should been added"); entries[3].LogLevel.Should().Be(LevelFlags.Warning, "because the third log entry should been added"); }
public void TestCopyFromLogFile_Contiguous() { var entries = new LogBufferList(Core.Columns.RawContent); entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> { { Core.Columns.RawContent, "I" } })); entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> { { Core.Columns.RawContent, "want" } })); entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> { { Core.Columns.RawContent, "a" } })); entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> { { Core.Columns.RawContent, "Clondyke" } })); entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> { { Core.Columns.RawContent, "Bar" } })); var logFile = new InMemoryLogSource(); logFile.AddEntry("Hello", LevelFlags.Debug); logFile.AddEntry("World!", LevelFlags.Info); entries.CopyFrom(Core.Columns.RawContent, 3, logFile, new LogSourceSection(0, 2)); entries.Count.Should().Be(5, "because the count shouldn't have been modified"); entries[0].RawContent.Should().Be("I", "because the first entry's raw content should not have been overwritten"); entries[1].RawContent.Should().Be("want", "because the second entry's raw content should not have been overwritten"); entries[2].RawContent.Should().Be("a", "because the third entry's raw content should not have been overwritten"); entries[3].RawContent.Should().Be("Hello", "because the fourth entry's raw content should have been overwritten"); entries[4].RawContent.Should().Be("World!", "because the fifth entry's raw content should have been overwritten"); }
public void TestRequestFullyCached_Contiguous_ReadFromMultiplePages() { var buffer = new PagedLogBuffer(1024, 10, Core.Columns.RawContent); var data = new LogBufferList(Core.Columns.Index, Core.Columns.RawContent); for (int i = 0; i < 5 * 1024; ++i) { data.Add(new LogEntry { Index = i, RawContent = i.ToString() }); } buffer.ResizeTo(data.Count); buffer.TryAdd(new LogSourceSection(0, data.Count), data, 0); var destination = new LogBufferArray(2048, Core.Columns.Index, Core.Columns.RawContent); var readOffset = 1024; buffer.TryGetEntries(new LogSourceSection(readOffset, destination.Count), destination, 0).Should().BeTrue("because all requested data is part of the cache"); for (int i = 0; i < destination.Count; ++i) { var logEntry = destination[i]; logEntry.Index.Should().Be(readOffset + i); logEntry.RawContent.Should().Be((readOffset + i).ToString()); } }
public void Setup2() { _scheduler = new ManualTaskScheduler(); _source = new Mock <ILogSource>(); _listeners = new LogSourceListenerCollection(_source.Object); _sourceEntries = new LogBufferList(Core.Columns.Index, Core.Columns.LogLevel, Core.Columns.Timestamp); _sourceProperties = new PropertiesBufferList(); _source.Setup(x => x.GetAllProperties(It.IsAny <IPropertiesBuffer>())) .Callback((IPropertiesBuffer destination) => _sourceProperties.CopyAllValuesTo(destination)); _source.Setup(x => x.GetProperty(It.IsAny <IPropertyDescriptor>())) .Returns((IPropertyDescriptor property) => _sourceProperties.GetValue(property)); _source.Setup(x => x.Columns).Returns(() => _sourceEntries.Columns); _source.Setup(x => x.AddListener(It.IsAny <ILogSourceListener>(), It.IsAny <TimeSpan>(), It.IsAny <int>())) .Callback((ILogSourceListener listener, TimeSpan maximumWaitTime, int maximumLineCount) => { _listeners.AddListener(listener, maximumWaitTime, maximumLineCount); }); _source.Setup(x => x.RemoveListener(It.IsAny <ILogSourceListener>())) .Callback((ILogSourceListener listener) => { _listeners.RemoveListener(listener); }); _source.Setup(x => x.GetEntries(It.IsAny <IReadOnlyList <LogLineIndex> >(), It.IsAny <ILogBuffer>(), It.IsAny <int>(), It.IsAny <LogSourceQueryOptions>())) .Callback((IReadOnlyList <LogLineIndex> sourceIndices, ILogBuffer destination, int destinationIndex, LogSourceQueryOptions queryOptions) => { _sourceEntries.CopyTo(new Int32View(sourceIndices), destination, destinationIndex); }); }
public void TestRequestPartiallyCached_Segmented_ReadFromTwoPages() { var buffer = new PagedLogBuffer(1024, 10, Core.Columns.RawContent); buffer.ResizeTo(12); var data = new LogBufferList(Core.Columns.Index, Core.Columns.RawContent) { new LogEntry(), new LogEntry { RawContent = "Dina", }, new LogEntry { RawContent = "Jesse" } }; buffer.TryAdd(new LogSourceSection(7, 2), data, 1); var destination = new LogBufferArray(11, Core.Columns.Index, Core.Columns.RawContent); buffer.TryGetEntries(new LogSourceSection(4, 5), destination, 6).Should().BeFalse("because we managed to only retrieve the data partially"); for (int i = 6; i < 9; ++i) { destination[i].Index.Should().Be(Core.Columns.Index.DefaultValue); destination[i].RawContent.Should().Be(Core.Columns.RawContent.DefaultValue); } destination[9].Index.Should().Be(7); destination[9].RawContent.Should().Be("Dina"); destination[10].Index.Should().Be(8); destination[10].RawContent.Should().Be("Jesse"); }
public void TestTryGetEntries_DestinationNull() { var buffer = new PagedLogBuffer(4, 2, Core.Columns.RawContent); buffer.ResizeTo(4); var data = new LogBufferList(Core.Columns.Index, Core.Columns.RawContent) { new LogEntry { RawContent = "A" }, new LogEntry { RawContent = "B" }, new LogEntry { RawContent = "C" }, new LogEntry { RawContent = "D" } }; buffer.TryAdd(new LogSourceSection(0, 8), data, 0); new Action(() => buffer.TryGetEntries(new LogSourceSection(0, 2), null, 1)) .Should().Throw <ArgumentNullException>("because the buffer is too small"); }
public void TestRemoveAt() { var entries = new LogBufferList(Core.Columns.DeltaTime); entries.Add(TimeSpan.FromSeconds(5)); entries.Add(TimeSpan.FromSeconds(6)); entries.Add(TimeSpan.FromSeconds(7)); entries.Count.Should().Be(3); entries[0].DeltaTime.Should().Be(TimeSpan.FromSeconds(5)); entries[1].DeltaTime.Should().Be(TimeSpan.FromSeconds(6)); entries[2].DeltaTime.Should().Be(TimeSpan.FromSeconds(7)); entries.RemoveAt(2); entries.Count.Should().Be(2); entries[0].DeltaTime.Should().Be(TimeSpan.FromSeconds(5)); entries[1].DeltaTime.Should().Be(TimeSpan.FromSeconds(6)); entries.RemoveAt(0); entries.Count.Should().Be(1); entries[0].DeltaTime.Should().Be(TimeSpan.FromSeconds(6)); entries.RemoveAt(0); entries.Count.Should().Be(0); }
public void TestTryGetEntries_DestinationTooSmall() { var buffer = new PagedLogBuffer(4, 2, Core.Columns.RawContent); buffer.ResizeTo(4); var data = new LogBufferList(Core.Columns.Index, Core.Columns.RawContent) { new LogEntry { RawContent = "A" }, new LogEntry { RawContent = "B" }, new LogEntry { RawContent = "C" }, new LogEntry { RawContent = "D" } }; buffer.TryAdd(new LogSourceSection(0, 8), data, 0); var destination = new LogBufferArray(2, Core.Columns.Index, Core.Columns.RawContent); destination[0].RawContent = "1"; destination[1].RawContent = "2"; new Action(() => buffer.TryGetEntries(new LogSourceSection(0, 2), destination, 1)) .Should().Throw <ArgumentException>("because the destination is too small"); destination[0].RawContent.Should().Be("1", "because the original data may not have been overwritten"); destination[1].RawContent.Should().Be("2", "because the original data may not have been overwritten"); }
protected override IReadOnlyLogEntry CreateDefault() { // TODO: Swap var buffer = new LogBufferList(Core.Columns.Minimum); buffer.AddEmpty(); return(buffer[0]); }
public void TestAddEmpty3() { var entries = new LogBufferList(Core.Columns.Timestamp); entries.AddEmpty(); entries.Count.Should().Be(1); entries[0].Timestamp.Should().Be(null); }
protected override IReadOnlyLogEntry CreateEmpty() { // TODO: Swap var buffer = new LogBufferList(); buffer.AddEmpty(); return(buffer[0]); }
public void TestInsertEmptyInvalidIndex([Values(-2, -1, 1, 42)] int invalidIndex) { var entries = new LogBufferList(Core.Columns.DeltaTime); entries.Count.Should().Be(0); new Action(() => entries.InsertEmpty(invalidIndex)).Should().Throw <ArgumentOutOfRangeException>(); entries.Count.Should().Be(0); }
public void TestAddEmpty4() { var entries = new LogBufferList(Core.Columns.DeltaTime); entries.AddEmpty(); entries.Count.Should().Be(1); entries[0].DeltaTime.Should().Be(null); }
public void TestAddEmpty1() { var entries = new LogBufferList(Core.Columns.LineNumber); entries.AddEmpty(); entries.Count.Should().Be(1); entries[0].LineNumber.Should().Be(0); }
public void TestAddEmpty2() { var entries = new LogBufferList(Core.Columns.RawContent); entries.AddEmpty(); entries.Count.Should().Be(1); entries[0].RawContent.Should().Be(null); }
public void TestEmptyConstruction2() { var entries = new LogBufferList(Core.Columns.DeltaTime, Core.Columns.ElapsedTime, Core.Columns.RawContent); entries.Count.Should().Be(0); entries.Columns.Should() .Equal(new object[] { Core.Columns.DeltaTime, Core.Columns.ElapsedTime, Core.Columns.RawContent }, "because the order columns should've been preserved"); }
public void TestInsertOneEntry() { var entries = new LogBufferList(Core.Columns.DeltaTime); entries.Insert(0, ReadOnlyLogEntry.Create(new[] { Core.Columns.DeltaTime }, new object[] { TimeSpan.FromHours(22) })); entries.Count.Should().Be(1); entries[0].DeltaTime.Should().Be(TimeSpan.FromHours(22)); }
public void TestAccessInvalidIndex([Range(-1, 1)] int invalidIndex) { var entries = new LogBufferList(Core.Columns.LineNumber); new Action(() => { var unused = entries[invalidIndex]; }).Should().Throw <ArgumentOutOfRangeException>(); }
public void TestIgnoreDataOutOfBounds() { var buffer = new PagedLogBuffer(4, 2, Core.Columns.RawContent); buffer.ResizeTo(4); var data = new LogBufferList(Core.Columns.Index, Core.Columns.RawContent) { new LogEntry { RawContent = "A" }, new LogEntry { RawContent = "B" }, new LogEntry { RawContent = "C" }, new LogEntry { RawContent = "D" }, new LogEntry { RawContent = "E" }, new LogEntry { RawContent = "F" }, new LogEntry { RawContent = "G" }, new LogEntry { RawContent = "H" }, }; buffer.TryAdd(new LogSourceSection(0, 8), data, 0); var destination = new LogBufferArray(8, Core.Columns.Index, PageBufferedLogSource.RetrievalState, Core.Columns.RawContent); buffer.TryGetEntries(new LogSourceSection(0, 8), destination, 0).Should().BeFalse("because even though we've tried to add 8 elements to the buffer, only the first 4 are part of the entire log file section and thus the others should have been ignored"); destination[0].RawContent.Should().Be("A"); destination[1].RawContent.Should().Be("B"); destination[2].RawContent.Should().Be("C"); destination[3].RawContent.Should().Be("D"); for (int i = 0; i < 4; ++i) { destination[i].GetValue(PageBufferedLogSource.RetrievalState).Should().Be(RetrievalState.Retrieved); } for (int i = 4; i < 8; ++i) { destination[i].RawContent.Should().Be(Core.Columns.RawContent.DefaultValue); destination[i].GetValue(PageBufferedLogSource.RetrievalState).Should().Be(RetrievalState.NotInSource); } }
public void TestCopyFromLogBuffer_OneColumn() { var columns = new IColumnDescriptor[] { Core.Columns.Message, Core.Columns.LogLevel, Core.Columns.LineNumber }; var entries = new[] { new LogEntry(columns) { Message = "Foo", LogLevel = LevelFlags.Fatal, LineNumber = 2 }, new LogEntry(columns) { Message = "Bar", LogLevel = LevelFlags.Info, LineNumber = 12 }, new LogEntry(columns) { Message = "Sup", LogLevel = LevelFlags.Debug, LineNumber = 42 } }; var buffer = Create(entries); buffer.Count.Should().Be(3); var source = new LogBufferList(columns) { new LogEntry(columns) { Message = "Hello", LogLevel = LevelFlags.Trace, LineNumber = 4 }, new LogEntry(columns) { Message = "World", LogLevel = LevelFlags.Trace, LineNumber = 5 }, new LogEntry(columns) { Message = "What", LogLevel = LevelFlags.Warning, LineNumber = 8 }, new LogEntry(columns) { Message = "Goes?", LogLevel = LevelFlags.None, LineNumber = 9 } }; buffer.CopyFrom(Core.Columns.LineNumber, 1, source, new[] { 3, 1 }); new Action(() => buffer.FillDefault(1, 3)).Should().Throw <ArgumentException>(); buffer[0].Message.Should().Be("Foo", "because the data may not have been modified"); buffer[0].LogLevel.Should().Be(LevelFlags.Fatal, "because the data may not have been modified"); buffer[0].LineNumber.Should().Be(2, "because the data may not have been modified"); buffer[1].Message.Should().Be("Bar", "because the data may not have been modified"); buffer[1].LogLevel.Should().Be(LevelFlags.Info, "because the data may not have been modified"); buffer[1].LineNumber.Should().Be(9); buffer[2].Message.Should().Be("Sup", "because the data may not have been modified"); buffer[2].LogLevel.Should().Be(LevelFlags.Debug, "because the data may not have been modified"); buffer[2].LineNumber.Should().Be(5); }
public void TestContains() { var entries = new LogBufferList(Core.Columns.DeltaTime, Core.Columns.ElapsedTime, Core.Columns.RawContent); entries.Contains(Core.Columns.DeltaTime).Should().BeTrue(); entries.Contains(Core.Columns.ElapsedTime).Should().BeTrue(); entries.Contains(Core.Columns.RawContent).Should().BeTrue(); entries.Contains(Core.Columns.LogLevel).Should().BeFalse("because we've not specified this column during construction"); entries.Contains(Core.Columns.Timestamp).Should().BeFalse("because we've not specified this column during construction"); }
public void TestClearOneEntry() { var entries = new LogBufferList(); entries.Add(); entries.Count.Should().Be(1); entries.Clear(); entries.Count.Should().Be(0); }
public void TestAddOneEntry() { var entries = new LogBufferList(Core.Columns.RawContent); entries.Count.Should().Be(0); entries.Add(ReadOnlyLogEntry.Create(new[] { Core.Columns.RawContent }, new[] { "Foobar" })); entries.Count.Should().Be(1); entries[0].RawContent.Should().Be("Foobar"); }
public void TestInsertInvalidIndex([Values(-2, -1, 1, 42)] int invalidIndex) { var entries = new LogBufferList(Core.Columns.ElapsedTime); var logEntry = ReadOnlyLogEntry.Create(new[] { Core.Columns.ElapsedTime }, new object[] { TimeSpan.FromHours(22) }); new Action(() => entries.Insert(invalidIndex, logEntry)) .Should().Throw <ArgumentOutOfRangeException>(); entries.Count.Should().Be(0); }
public void TestClearEmpty() { var entries = new LogBufferList(Core.Columns.ElapsedTime); entries.Count.Should().Be(0); entries.Columns.Should().Equal(Core.Columns.ElapsedTime); entries.Clear(); entries.Count.Should().Be(0); entries.Columns.Should().Equal(Core.Columns.ElapsedTime); }