-
-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fd0f9b8
commit e165d40
Showing
9 changed files
with
295 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,170 @@ | ||
using JasperFx.Core.Reflection; | ||
using ChaosTesting.Scripts; | ||
using JasperFx.Core.Reflection; | ||
using Shouldly; | ||
using Wolverine.RabbitMQ; | ||
using Xunit.Abstractions; | ||
using Xunit.Sdk; | ||
|
||
namespace ChaosTesting; | ||
|
||
public class ChaosSpecifications | ||
{ | ||
static ChaosSpecifications() | ||
private readonly ITestOutputHelper _output; | ||
private static TransportConfiguration RabbitMqOneInlineListener = new TransportConfiguration("Rabbit MQ Inline w/ One Listener") | ||
{ | ||
AllScripts = typeof(ChaosSpecifications) | ||
.Assembly | ||
.GetTypes() | ||
.Where(x => x.IsConcreteTypeOf<ChaosScript>()) | ||
.Select(Activator.CreateInstance) | ||
.OfType<ChaosScript>() | ||
.ToArray(); | ||
} | ||
|
||
public static ChaosScript[] AllScripts { get; } | ||
ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting(), | ||
ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting() | ||
}; | ||
|
||
private static TransportConfiguration RabbitMqFiveParallelInlineListeners = new TransportConfiguration("Rabbit MQ Inline w/ Five Listeners") | ||
{ | ||
ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.ListenerCount(5)), | ||
ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting() | ||
}; | ||
|
||
private static TransportConfiguration RabbitMqBufferedListener = new TransportConfiguration("Rabbit MQ Buffered w/ 1 Listener") | ||
{ | ||
ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.BufferedInMemory()), | ||
ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureSenders(x => x.BufferedInMemory()) | ||
}; | ||
|
||
private static TransportConfiguration RabbitMqDurableListener = new TransportConfiguration("Rabbit MQ Durable w/ 1 Listener") | ||
{ | ||
ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.UseDurableInbox()), | ||
ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureSenders(x => x.UseDurableOutbox()) | ||
}; | ||
|
||
private static TransportConfiguration RabbitMqFiveBufferedListeners = new TransportConfiguration("Rabbit MQ Buffered w/ 5 Listeners") | ||
{ | ||
ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.BufferedInMemory().ListenerCount(5)), | ||
ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureSenders(x => x.BufferedInMemory()) | ||
}; | ||
|
||
private static TransportConfiguration RabbitMqFiveDurableListeners = new TransportConfiguration("Rabbit MQ Durable w/ 5 Listeners") | ||
{ | ||
ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.UseDurableInbox().ListenerCount(5)), | ||
ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureSenders(x => x.UseDurableOutbox()) | ||
}; | ||
|
||
public static IMessageStorageStrategy[] Storage { get; } = { new MartenStorageStrategy() }; | ||
|
||
public static IEnumerable<TransportConfiguration> TransportConfigurations() | ||
public ChaosSpecifications(ITestOutputHelper output) | ||
{ | ||
yield return new TransportConfiguration("Rabbit MQ Inline w/ One Listener") | ||
{ | ||
ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting(), | ||
ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting() | ||
}; | ||
|
||
// yield return new TransportConfiguration("Rabbit MQ Inline w/ Five Listeners") | ||
// { | ||
// ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.ListenerCount(5)), | ||
// ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting() | ||
// }; | ||
// | ||
// yield return new TransportConfiguration("Rabbit MQ Buffered w/ 1 Listener") | ||
// { | ||
// ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.BufferedInMemory()), | ||
// ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureSenders(x => x.BufferedInMemory()) | ||
// }; | ||
// | ||
// yield return new TransportConfiguration("Rabbit MQ Buffered w/ 5 Listeners") | ||
// { | ||
// ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.BufferedInMemory().ListenerCount(5)), | ||
// ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureSenders(x => x.BufferedInMemory()) | ||
// }; | ||
// | ||
// yield return new TransportConfiguration("Rabbit MQ Durable w/ 1 Listener") | ||
// { | ||
// ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.UseDurableInbox()), | ||
// ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureSenders(x => x.UseDurableOutbox()) | ||
// }; | ||
// | ||
// yield return new TransportConfiguration("Rabbit MQ Durable w/ 5 Listeners") | ||
// { | ||
// ConfigureReceiver = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureListeners(x => x.UseDurableInbox().ListenerCount(5)), | ||
// ConfigureSender = opts => opts.UseRabbitMq().AutoProvision().UseConventionalRouting().ConfigureSenders(x => x.UseDurableOutbox()) | ||
// }; | ||
|
||
|
||
_output = output; | ||
} | ||
|
||
public static IEnumerable<object[]> Data() | ||
protected async Task execute<TStorage, TScript>(TransportConfiguration configuration) | ||
where TStorage : IMessageStorageStrategy, new() | ||
where TScript : ChaosScript, new() | ||
{ | ||
foreach (var transportConfiguration in TransportConfigurations()) | ||
{ | ||
foreach (var storageStrategy in Storage) | ||
{ | ||
foreach (var script in AllScripts) | ||
{ | ||
yield return new object[] {transportConfiguration, storageStrategy, script}; | ||
} | ||
} | ||
} | ||
} | ||
|
||
[Theory] | ||
[MemberData(nameof(Data))] | ||
public async Task chaos_and_load_specs(TransportConfiguration transportConfiguration, IMessageStorageStrategy storageStrategy, ChaosScript script) | ||
{ | ||
using var driver = new ChaosDriver(storageStrategy, transportConfiguration); | ||
using var driver = new ChaosDriver(_output, new TStorage(), configuration); | ||
await driver.InitializeAsync(); | ||
|
||
var script = new TScript(); | ||
await script.Drive(driver); | ||
|
||
var completed = await driver.WaitForAllMessagingToComplete(script.TimeOut); | ||
|
||
completed.ShouldBeTrue(); | ||
} | ||
|
||
[Fact] | ||
public Task RabbitMqOneInlineListener_Marten_Simple() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqOneInlineListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveParallelInlineListeners_Marten_Simple() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveParallelInlineListeners); | ||
|
||
[Fact] | ||
public Task RabbitMqBufferedListener_Marten_Simple() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqBufferedListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveBufferedListeners_Marten_Simple() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveBufferedListeners); | ||
|
||
|
||
[Fact] | ||
public Task RabbitMqDurableListener_Marten_Simple() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqDurableListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveDurableListeners_Marten_Simple() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveDurableListeners); | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
[Fact] | ||
public Task RabbitMqOneInlineListener_Marten_ReceiverStartsLater() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqOneInlineListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveParallelInlineListeners_Marten_ReceiverStartsLater() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveParallelInlineListeners); | ||
|
||
[Fact] | ||
public Task RabbitMqBufferedListener_Marten_ReceiverStartsLater() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqBufferedListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveBufferedListeners_Marten_ReceiverStartsLater() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveBufferedListeners); | ||
|
||
|
||
[Fact] | ||
public Task RabbitMqDurableListener_Marten_ReceiverStartsLater() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqDurableListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveDurableListeners_Marten_ReceiverStartsLater() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveDurableListeners); | ||
|
||
|
||
|
||
|
||
|
||
|
||
[Fact] | ||
public Task RabbitMqOneInlineListener_Marten_ReceiverGoesUpAndDown() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqOneInlineListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveParallelInlineListeners_Marten_ReceiverGoesUpAndDown() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveParallelInlineListeners); | ||
|
||
[Fact] | ||
public Task RabbitMqBufferedListener_Marten_ReceiverGoesUpAndDown() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqBufferedListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveBufferedListeners_Marten_ReceiverGoesUpAndDown() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveBufferedListeners); | ||
|
||
|
||
[Fact] | ||
public Task RabbitMqDurableListener_Marten_ReceiverGoesUpAndDown() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqDurableListener); | ||
|
||
[Fact] | ||
public Task RabbitMqFiveDurableListeners_Marten_ReceiverGoesUpAndDown() => | ||
execute<MartenStorageStrategy, Simplistic>(RabbitMqFiveDurableListeners); | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using Microsoft.Extensions.Logging; | ||
using Xunit.Abstractions; | ||
|
||
namespace ChaosTesting; | ||
|
||
public class OutputLoggerProvider : ILoggerProvider | ||
{ | ||
private readonly ITestOutputHelper _output; | ||
|
||
public OutputLoggerProvider(ITestOutputHelper output) | ||
{ | ||
_output = output; | ||
} | ||
|
||
|
||
public void Dispose() | ||
{ | ||
|
||
} | ||
|
||
public ILogger CreateLogger(string categoryName) | ||
{ | ||
return new XUnitLogger(_output, categoryName); | ||
} | ||
} | ||
|
||
public class XUnitLogger : ILogger | ||
{ | ||
private readonly ITestOutputHelper _testOutputHelper; | ||
private readonly string _categoryName; | ||
|
||
public XUnitLogger(ITestOutputHelper testOutputHelper, string categoryName) | ||
{ | ||
_testOutputHelper = testOutputHelper; | ||
_categoryName = categoryName; | ||
} | ||
|
||
public class Disposable : IDisposable | ||
{ | ||
public void Dispose() | ||
{ | ||
} | ||
} | ||
|
||
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None; | ||
|
||
public IDisposable BeginScope<TState>(TState state) => new Disposable(); | ||
|
||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) | ||
{ | ||
if (exception is DivideByZeroException) return; | ||
if (exception is BadImageFormatException) return; | ||
|
||
if (_categoryName == "Wolverine.Runtime.WolverineRuntime/Information" && | ||
logLevel == LogLevel.Information) return; | ||
|
||
var text = formatter(state, exception); | ||
|
||
_testOutputHelper.WriteLine($"{_categoryName}/{logLevel}: {text}"); | ||
|
||
if (exception != null) | ||
{ | ||
_testOutputHelper.WriteLine(exception.ToString()); | ||
} | ||
} | ||
} |
Oops, something went wrong.