/// <summary> /// Applies Capacity+1 times the same test to the same buffer "logical" content but with /// different internal offsets each time. /// The "logical" initial buffer content is restored each time and at the end of the test. /// </summary> static void TestWithInternalOffsets <T>(FIFOBuffer <T> f, Action <FIFOBuffer <T> > testPredicate) { var saved = f.ToArray(); for (int iTry = 0; iTry <= f.Capacity; ++iTry) { f.Clear(); for (int i = 0; i < iTry; ++i) { f.Push(default(T)); } foreach (var i in saved) { f.Push(i); } while (f.Count > saved.Length) { f.Pop(); } f.SequenceEqual(saved).Should().BeTrue(); testPredicate(f); } foreach (var i in saved) { f.Push(i); } f.Truncate(saved.Length); }
static void CheckOneValueType <T>(FIFOBuffer <T> f, T value, T otherValue) where T : struct { CheckOnlyOneValueType <T>(f, value, otherValue); f.Pop().Should().Be(value); AssertEmpty(f); f.Push(value); CheckOnlyOneValueType <T>(f, value, otherValue); }
static void CheckOneValueType <T>(FIFOBuffer <T> f, T value, T otherValue) where T : struct { CheckOnlyOneValueType <T>(f, value, otherValue); Assert.That(f.Pop(), Is.EqualTo(value)); AssertEmpty(f); f.Push(value); CheckOnlyOneValueType <T>(f, value, otherValue); }
private static void AssertEmpty <T>(FIFOBuffer <T> f) { Assert.Throws <IndexOutOfRangeException>(() => Console.WriteLine(f[-1])); Assert.Throws <IndexOutOfRangeException>(() => Console.WriteLine(f[0])); Assert.Throws <IndexOutOfRangeException>(() => Console.WriteLine(f[1])); Assert.Throws <InvalidOperationException>(() => f.Pop()); Assert.That(f.Count, Is.EqualTo(0)); Assert.That(f, Is.Empty); AssertContains(f); }
/// <summary> /// Sends the log entry: creates the sender if necessary and manages the buffer. /// </summary> /// <param name="monitor">The monitor to use.</param> /// <param name="logEvent">The log entry to send.</param> /// <returns>The awaitable.</returns> /// <exception cref="CKException"> /// If the sender has not been created yet and the application identity is ready /// but CreateSenderAsync returned null: the exception will remove this handler from the sink's handler list. /// </exception> public virtual async ValueTask HandleAsync(IActivityMonitor monitor, IMulticastLogEntry logEvent) { if (_sender == null && SenderCanBeCreated) { _sender = await CreateSenderAsync(monitor); if (_sender == null) { throw new CKException($"Unable to create the sender."); } } if (_sender != null) { if (_buffer.Count > 0) { while (_buffer.Count > 0) { if (!_sender.IsActuallyConnected || !await _sender.TrySendAsync(monitor, _buffer.Peek())) { _buffer.Push(logEvent); return; } _buffer.Pop(); } } if (!_sender.IsActuallyConnected || !await _sender.TrySendAsync(monitor, logEvent)) { _buffer.Push(logEvent); } else if (!_firstSuccess) { _firstSuccess = true; if (_buffer.Capacity != _config.LostBufferSize) { monitor.Info($"Successfully sent the first logs: resizing buffer from '{_buffer.Capacity}' to '{_config.LostBufferSize}'."); _buffer.Capacity = _config.LostBufferSize; } } } else { _buffer.Push(logEvent); } }
public void FIFO_with_one_and_only_one_Value_Type() { FIFOBuffer <int> f = new FIFOBuffer <int>(1); AssertEmpty(f); f.Push(5); CheckOneValueType(f, 5, 50); f.Pop(); f.Push(0); CheckOneValueType(f, 0, 5); f.Push(1); CheckOneValueType(f, 1, 0); f.Push(2); CheckOneValueType(f, 2, 0); int iType = f.IndexOf(2); int iBoxed = f.IndexOf((object)2); iType.Should().Be(iBoxed); }
public void FIFOOneValueType() { FIFOBuffer <int> f = new FIFOBuffer <int>(1); AssertEmpty(f); f.Push(5); CheckOneValueType(f, 5, 50); f.Pop(); f.Push(0); CheckOneValueType(f, 0, 5); f.Push(1); CheckOneValueType(f, 1, 0); f.Push(2); CheckOneValueType(f, 2, 0); int iType = f.IndexOf(2); int iBoxed = f.IndexOf((object)2); Assert.That(iType == iBoxed); }