Пример #1
0
        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);
        }
Пример #2
0
        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");
        }
Пример #3
0
        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>();
        }
Пример #4
0
        public void TestResizeAddRows()
        {
            var entries = new LogBufferList(Core.Columns.RawContent);

            entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> {
                { Core.Columns.RawContent, "Hello!" }
            }));
            entries.Resize(3);
            entries.Count.Should().Be(3);
            entries[0].RawContent.Should().Be("Hello!", "because the content of the first cell should have been left untouched");
            entries[1].RawContent.Should().BeNull("because an default value should have been placed in the newly added cell");
            entries[2].RawContent.Should().BeNull("because an default value should have been placed in the newly added cell");
        }
Пример #5
0
        public void TestFillInvalidLength()
        {
            var buffer = new LogBufferList(Core.Columns.LineNumber);

            buffer.Resize(10);
            buffer.Fill(Core.Columns.LineNumber, 42, 0, 10);
            new Action(() => buffer.Fill(Core.Columns.LineNumber, 9001, 0, 11))
            .Should().Throw <ArgumentException>();

            for (int i = 0; i < 10; ++i)
            {
                buffer[i].LineNumber.Should().Be(42, "because nothing may have been overwritten");
            }
        }
Пример #6
0
        public void TestResizeRemoveRows()
        {
            var entries = new LogBufferList(Core.Columns.RawContent);

            entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> {
                { Core.Columns.RawContent, "Hello," }
            }));
            entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> {
                { Core.Columns.RawContent, "World!" }
            }));
            entries.Resize(1);
            entries.Count.Should().Be(1, "because we just removed a cell");
            entries[0].RawContent.Should().Be("Hello,", "Because the content of the first cell should been left untouched");
        }
Пример #7
0
        public void TestResizeInvalidCount()
        {
            var entries = new LogBufferList(Core.Columns.RawContent);

            entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> {
                { Core.Columns.RawContent, "Hello," }
            }));
            entries.Add(new ReadOnlyLogEntry(new Dictionary <IColumnDescriptor, object> {
                { Core.Columns.RawContent, "World!" }
            }));
            new Action(() => entries.Resize(-1)).Should().Throw <ArgumentOutOfRangeException>();
            entries.Count.Should().Be(2, "because the list shouldn't have been modified");
            entries[0].RawContent.Should().Be("Hello,", "Because the content of the first cell should been left untouched");
            entries[1].RawContent.Should().Be("World!", "Because the content of the second cell should been left untouched");
        }
Пример #8
0
        public void TestFill()
        {
            var buffer = new LogBufferList(Core.Columns.LineNumber);

            buffer.Resize(10);
            buffer.Fill(Core.Columns.LineNumber, 42, 2, 4);
            buffer.Fill(Core.Columns.LineNumber, 1337, 7, 2);

            buffer[0].LineNumber.Should().Be(Core.Columns.LineNumber.DefaultValue);
            buffer[1].LineNumber.Should().Be(Core.Columns.LineNumber.DefaultValue);
            buffer[2].LineNumber.Should().Be(42);
            buffer[3].LineNumber.Should().Be(42);
            buffer[4].LineNumber.Should().Be(42);
            buffer[5].LineNumber.Should().Be(42);
            buffer[6].LineNumber.Should().Be(Core.Columns.LineNumber.DefaultValue);
            buffer[7].LineNumber.Should().Be(1337);
            buffer[8].LineNumber.Should().Be(1337);
            buffer[9].LineNumber.Should().Be(Core.Columns.LineNumber.DefaultValue);
        }
Пример #9
0
        public void TestCopyFromArray_Empty()
        {
            var entries = new LogBufferList(Core.Columns.LogLevel);

            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);
            entries[1].LogLevel.Should().Be(LevelFlags.Debug);
            entries[2].LogLevel.Should().Be(LevelFlags.Error);
            entries[3].LogLevel.Should().Be(LevelFlags.Warning);
        }
Пример #10
0
        public void TestContainsAny()
        {
            var buffer = new LogBufferList(Core.Columns.LineNumber);

            buffer.Resize(3);
            buffer[0].LineNumber = 1;
            buffer[1].LineNumber = 2;
            buffer[2].LineNumber = 3;

            buffer.ContainsAny(Core.Columns.LineNumber, 1, new Int32Range(0, 1)).Should().BeTrue();
            buffer.ContainsAny(Core.Columns.LineNumber, 1, new Int32Range(0, 2)).Should().BeTrue();
            buffer.ContainsAny(Core.Columns.LineNumber, 1, new Int32Range(0, 3)).Should().BeTrue();

            buffer.ContainsAny(Core.Columns.LineNumber, 1, new Int32Range(1, 1)).Should().BeFalse();
            buffer.ContainsAny(Core.Columns.LineNumber, 1, new Int32Range(1, 2)).Should().BeFalse();
            buffer.ContainsAny(Core.Columns.LineNumber, 1, new Int32Range(2, 1)).Should().BeFalse();

            buffer.ContainsAny(Core.Columns.LineNumber, 2, new Int32Range(0, 3)).Should().BeTrue();
            buffer.ContainsAny(Core.Columns.LineNumber, 2, new Int32Range(0, 1)).Should().BeFalse();
            buffer.ContainsAny(Core.Columns.LineNumber, 2, new Int32Range(2, 1)).Should().BeFalse();
        }
Пример #11
0
        public void UpdateVisibleLines()
        {
            _visibleTextLines.Clear();
            if (_logSource == null)
            {
                return;
            }

            try
            {
                _visibleBufferBuffer.Clear();
                _visibleBufferBuffer.Resize(_currentlyVisibleSection.Count);
                if (_currentlyVisibleSection.Count > 0)
                {
                    // We don't want to block the UI thread for very long at all so we instruct the log source to only
                    // fetch data from the cache, but to fetch missing data for later (from the source).
                    var queryOptions = new LogSourceQueryOptions(LogSourceQueryMode.FromCache | LogSourceQueryMode.FetchForLater, TimeSpan.Zero);
                    _logSource.GetEntries(_currentlyVisibleSection, _visibleBufferBuffer, 0, queryOptions);

                    // Now comes the fun part. We need to detect if we could fetch *all* the data.
                    // This is done by inspecting the BufferedLogSource.RetrievalState - if we encounter any NotCached value,
                    // then the entry is part of the source, but was not cached at the time of trying to access it.
                    // If that's the case, we will instruct this canvas to re-fetch the once more in a bit. This loop will terminate once the
                    // cache has managed to fetch the desired data which should happen some time...
                    if (_visibleBufferBuffer.ContainsAny(PageBufferedLogSource.RetrievalState,
                                                         RetrievalState.NotCached,
                                                         new Int32Range(offset: 0, _currentlyVisibleSection.Count)))
                    {
                        if (!_requiresFurtherUpdate)
                        {
                            Log.DebugFormat("Requires further update (at least one entry is not in cache)");
                            _requiresFurtherUpdate = true;
                            _updateStart           = DateTime.Now;
                        }
                    }
                    else
                    {
                        if (_requiresFurtherUpdate)
                        {
                            var elapsed = DateTime.Now - _updateStart;
                            Log.DebugFormat("No longer requires further update (all retrieved log entries are in cache), took {0:F1}ms", elapsed.TotalMilliseconds);
                            _requiresFurtherUpdate = false;
                        }
                    }

                    for (int i = 0; i < _currentlyVisibleSection.Count; ++i)
                    {
                        var line = new TextLine(_visibleBufferBuffer[i], _hoveredIndices, _selectedIndices,
                                                _colorByLevel, _textSettings, _textBrushes)
                        {
                            IsFocused     = IsFocused,
                            SearchResults = _searchResults
                        };
                        _visibleTextLines.Add(line);
                    }
                }

                Action fn = VisibleLinesChanged;
                fn?.Invoke();

                InvalidateVisual();
            }
            catch (ArgumentOutOfRangeException e)
            {
                Log.DebugFormat("Caught exception while trying to update text: {0}", e);
            }
            catch (IndexOutOfRangeException e)
            {
                Log.DebugFormat("Caught exception while trying to update text: {0}", e);
            }
        }