Skip to content

Commit

Permalink
Remove _sink field
Browse files Browse the repository at this point in the history
Instantiate sink in in test instead. Response to feedback in #21
  • Loading branch information
cocowalla committed Aug 7, 2017
1 parent 188741e commit 3e5a186
Showing 1 changed file with 92 additions and 83 deletions.
175 changes: 92 additions & 83 deletions test/Serilog.Sinks.Async.Tests/BackgroundWorkerSinkSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,15 @@

namespace Serilog.Sinks.Async.Tests
{
public class BackgroundWorkerSinkSpec : IDisposable
public class BackgroundWorkerSinkSpec
{
readonly Logger _logger;
readonly MemorySink _innerSink;
BackgroundWorkerSink _sink;

public BackgroundWorkerSinkSpec()
{
_innerSink = new MemorySink();
_logger = new LoggerConfiguration().WriteTo.Sink(_innerSink).CreateLogger();
_sink = new BackgroundWorkerSink(_logger, 10000, false);
}

public void Dispose()
{
_sink.Dispose();
}

[Fact]
Expand All @@ -38,118 +31,134 @@ public void WhenCtorWithNullSink_ThenThrows()
[Fact]
public async Task WhenEmitSingle_ThenRelaysToInnerSink()
{
var logEvent = CreateEvent();
_sink.Emit(logEvent);
using (var sink = this.CreateSinkWithDefaultOptions())
{
var logEvent = CreateEvent();

sink.Emit(logEvent);

await Task.Delay(TimeSpan.FromSeconds(3));
await Task.Delay(TimeSpan.FromSeconds(3));

Assert.Equal(1, _innerSink.Events.Count);
Assert.Equal(1, _innerSink.Events.Count);
}
}

[Fact]
public async Task WhenInnerEmitThrows_ThenContinuesRelaysToInnerSink()
{
_innerSink.ThrowAfterCollecting = true;

var events = new List<LogEvent>
using (var sink = this.CreateSinkWithDefaultOptions())
{
CreateEvent(),
CreateEvent(),
CreateEvent()
};
events.ForEach(e => _sink.Emit(e));
_innerSink.ThrowAfterCollecting = true;

await Task.Delay(TimeSpan.FromSeconds(3));
var events = new List<LogEvent>
{
CreateEvent(),
CreateEvent(),
CreateEvent()
};
events.ForEach(e => sink.Emit(e));

await Task.Delay(TimeSpan.FromSeconds(3));

Assert.Equal(3, _innerSink.Events.Count);
Assert.Equal(3, _innerSink.Events.Count);
}
}

[Fact]
public async Task WhenEmitMultipleTimes_ThenRelaysToInnerSink()
{
var events = new List<LogEvent>
using (var sink = this.CreateSinkWithDefaultOptions())
{
CreateEvent(),
CreateEvent(),
CreateEvent()
};

events.ForEach(e => { _sink.Emit(e); });
var events = new List<LogEvent>
{
CreateEvent(),
CreateEvent(),
CreateEvent()
};
events.ForEach(e => { sink.Emit(e); });

await Task.Delay(TimeSpan.FromSeconds(3));
await Task.Delay(TimeSpan.FromSeconds(3));

Assert.Equal(3, _innerSink.Events.Count);
Assert.Equal(3, _innerSink.Events.Count);
}
}

[Fact]
public async Task WhenQueueFull_ThenDropsEvents()
{
_sink = new BackgroundWorkerSink(_logger, 1, false);

// Cause a delay when emmitting to the inner sink, allowing us to fill the queue to capacity
// after the first event is popped
_innerSink.DelayEmit = TimeSpan.FromMilliseconds(300);

var events = new List<LogEvent>
using (var sink = new BackgroundWorkerSink(_logger, 1, false))
{
CreateEvent(),
CreateEvent(),
CreateEvent(),
CreateEvent(),
CreateEvent()
};
events.ForEach(e =>
{
var sw = Stopwatch.StartNew();
_sink.Emit(e);
sw.Stop();
// Cause a delay when emmitting to the inner sink, allowing us to fill the queue to capacity
// after the first event is popped
_innerSink.DelayEmit = TimeSpan.FromMilliseconds(300);

var events = new List<LogEvent>
{
CreateEvent(),
CreateEvent(),
CreateEvent(),
CreateEvent(),
CreateEvent()
};
events.ForEach(e =>
{
var sw = Stopwatch.StartNew();
sink.Emit(e);
sw.Stop();

Assert.True(sw.ElapsedMilliseconds < 200, "Should not block the caller when the queue is full");
});
Assert.True(sw.ElapsedMilliseconds < 200, "Should not block the caller when the queue is full");
});

// If we *weren't* dropped events, the delay in the inner sink would mean the 5 events would take
// at least 15 seconds to process
await Task.Delay(TimeSpan.FromSeconds(2));
// If we *weren't* dropped events, the delay in the inner sink would mean the 5 events would take
// at least 15 seconds to process
await Task.Delay(TimeSpan.FromSeconds(2));

// Events should be dropped
Assert.Equal(2, _innerSink.Events.Count);
// Events should be dropped
Assert.Equal(2, _innerSink.Events.Count);
}
}

[Fact]
public async Task WhenQueueFull_ThenBlocks()
{
_sink = new BackgroundWorkerSink(_logger, 1, true);

// Cause a delay when emmitting to the inner sink, allowing us to fill the queue to capacity
// after the first event is popped
_innerSink.DelayEmit = TimeSpan.FromMilliseconds(300);

var events = new List<LogEvent>
using (var sink = new BackgroundWorkerSink(_logger, 1, true))
{
CreateEvent(),
CreateEvent(),
CreateEvent()
};
// Cause a delay when emmitting to the inner sink, allowing us to fill the queue to capacity
// after the first event is popped
_innerSink.DelayEmit = TimeSpan.FromMilliseconds(300);

int i = 0;
events.ForEach(e =>
{
var sw = Stopwatch.StartNew();
_sink.Emit(e);
sw.Stop();

// Emit should return immediately the first time, since the queue is not yet full. On
// subsequent calls, the queue should be full, so we should be blocked
if (i > 0)
var events = new List<LogEvent>
{
Assert.True(sw.ElapsedMilliseconds > 200, "Should block the caller when the queue is full");
}
});
CreateEvent(),
CreateEvent(),
CreateEvent()
};

await Task.Delay(TimeSpan.FromSeconds(2));
int i = 0;
events.ForEach(e =>
{
var sw = Stopwatch.StartNew();
sink.Emit(e);
sw.Stop();

// Emit should return immediately the first time, since the queue is not yet full. On
// subsequent calls, the queue should be full, so we should be blocked
if (i > 0)
{
Assert.True(sw.ElapsedMilliseconds > 200, "Should block the caller when the queue is full");
}
});

await Task.Delay(TimeSpan.FromSeconds(2));

// No events should be dropped
Assert.Equal(3, _innerSink.Events.Count);
}
}

// No events should be dropped
Assert.Equal(3, _innerSink.Events.Count);
private BackgroundWorkerSink CreateSinkWithDefaultOptions()
{
return new BackgroundWorkerSink(_logger, 10000, false);
}

private static LogEvent CreateEvent()
Expand Down

0 comments on commit 3e5a186

Please sign in to comment.