Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 254 additions & 0 deletions Shared.EventStore.Tests/ApplicationBuilderExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Moq;
using Shared.EventStore.EventHandling;
using Shared.EventStore.Extensions;
using Shared.EventStore.SubscriptionWorker;
using Shouldly;
using Xunit;
using Xunit.Abstractions;

namespace Shared.EventStore.Tests
{
public class ApplicationBuilderExtensionsTests
{
private readonly ITestOutputHelper TestOutputHelper;

public ApplicationBuilderExtensionsTests(ITestOutputHelper testOutputHelper) {
this.TestOutputHelper = testOutputHelper;
}

[Fact]
public void ApplicationBuilderExtensions_ConfigureSubscriptions_WorkerListReturned()
{
Mock<IApplicationBuilder> appBuilder = new Mock<IApplicationBuilder>();
Mock<ISubscriptionRepository> subscriptionRepository = new Mock<ISubscriptionRepository>();

SubscriptionWorkersRoot config = new SubscriptionWorkersRoot {
SubscriptionWorkers = new List<SubscriptionWorkerConfig>()
{
new SubscriptionWorkerConfig
{
Enabled = true,
IsOrdered = true,
},
new SubscriptionWorkerConfig
{
Enabled = true,
IsOrdered = false,
InstanceCount = 1,
}
}
};
Mock<IDomainEventHandlerResolver> deh = new Mock<IDomainEventHandlerResolver>();
String eventStoreConnectionString = "esdb://192.168.0.133:2113?tls=true&tlsVerifyCert=false";
Dictionary<String, IDomainEventHandlerResolver> eventHandlerResolvers = new();
eventHandlerResolvers.Add("Ordered", deh.Object);
eventHandlerResolvers.Add("Main", deh.Object);
Action<TraceEventType, String, String> traceHandler = (et, type, msg)=> { TestOutputHelper.WriteLine(msg); };
var result = IApplicationBuilderExtenstions.ConfigureSubscriptions(subscriptionRepository.Object, config,
eventStoreConnectionString, eventHandlerResolvers, traceHandler);
result.Count.ShouldBe(2);
}

[Fact]
public void ApplicationBuilderExtensions_ConfigureSubscriptions_NoneEnabled_WorkerListReturned()
{
Mock<IApplicationBuilder> appBuilder = new Mock<IApplicationBuilder>();
Mock<ISubscriptionRepository> subscriptionRepository = new Mock<ISubscriptionRepository>();

SubscriptionWorkersRoot config = new SubscriptionWorkersRoot
{
SubscriptionWorkers = new List<SubscriptionWorkerConfig>()
{
new SubscriptionWorkerConfig
{
Enabled = false,
IsOrdered = true,
},
new SubscriptionWorkerConfig
{
Enabled = false,
IsOrdered = false,
InstanceCount = 1,
}
}
};
Mock<IDomainEventHandlerResolver> deh = new Mock<IDomainEventHandlerResolver>();
String eventStoreConnectionString = "esdb://192.168.0.133:2113?tls=true&tlsVerifyCert=false";
Dictionary<String, IDomainEventHandlerResolver> eventHandlerResolvers = new();
eventHandlerResolvers.Add("Ordered", deh.Object);
eventHandlerResolvers.Add("Main", deh.Object);
Action<TraceEventType, String, String> traceHandler = (et, type, msg) => { TestOutputHelper.WriteLine(msg); };
var result = IApplicationBuilderExtenstions.ConfigureSubscriptions(subscriptionRepository.Object, config,
eventStoreConnectionString, eventHandlerResolvers, traceHandler);
result.Count.ShouldBe(0);
}

[Fact]
public void ApplicationBuilderExtensions_ConfigureSubscriptions_NoWorkers_WorkerListReturned()
{
Mock<IApplicationBuilder> appBuilder = new Mock<IApplicationBuilder>();
Mock<ISubscriptionRepository> subscriptionRepository = new Mock<ISubscriptionRepository>();

SubscriptionWorkersRoot config = new SubscriptionWorkersRoot
{
SubscriptionWorkers = new List<SubscriptionWorkerConfig>()
};
Mock<IDomainEventHandlerResolver> deh = new Mock<IDomainEventHandlerResolver>();
String eventStoreConnectionString = "esdb://192.168.0.133:2113?tls=true&tlsVerifyCert=false";
Dictionary<String, IDomainEventHandlerResolver> eventHandlerResolvers = new();
Action<TraceEventType, String, String> traceHandler = null;
var result = IApplicationBuilderExtenstions.ConfigureSubscriptions(subscriptionRepository.Object, config,
eventStoreConnectionString, eventHandlerResolvers, traceHandler);
result.Count.ShouldBe(0);
}

[Fact]
public void ApplicationBuilderExtensions_ConfigureSubscriptions_OrderedOnlyWorkers_WorkerListReturned()
{
Mock<IApplicationBuilder> appBuilder = new Mock<IApplicationBuilder>();
Mock<ISubscriptionRepository> subscriptionRepository = new Mock<ISubscriptionRepository>();

SubscriptionWorkersRoot config = new SubscriptionWorkersRoot
{
SubscriptionWorkers = new List<SubscriptionWorkerConfig>
{
new SubscriptionWorkerConfig
{
Enabled = true,
IsOrdered = true,
},
}
};
Mock<IDomainEventHandlerResolver> deh = new Mock<IDomainEventHandlerResolver>();
String eventStoreConnectionString = "esdb://192.168.0.133:2113?tls=true&tlsVerifyCert=false";
Dictionary<String, IDomainEventHandlerResolver> eventHandlerResolvers = new();
eventHandlerResolvers.Add("Ordered", deh.Object);
Action<TraceEventType, String, String> traceHandler = (et, type, msg) => { TestOutputHelper.WriteLine(msg); };
var result = IApplicationBuilderExtenstions.ConfigureSubscriptions(subscriptionRepository.Object, config,
eventStoreConnectionString, eventHandlerResolvers, traceHandler);
result.Count.ShouldBe(1);
result.Single().InflightMessages.ShouldBe(1);
}

[Fact]
public void ApplicationBuilderExtensions_ConfigureSubscriptions_OrderedOnlyWorkers_NoHandlers_WorkerListReturned()
{
Mock<IApplicationBuilder> appBuilder = new Mock<IApplicationBuilder>();
Mock<ISubscriptionRepository> subscriptionRepository = new Mock<ISubscriptionRepository>();

SubscriptionWorkersRoot config = new SubscriptionWorkersRoot
{
SubscriptionWorkers = new List<SubscriptionWorkerConfig>
{
new SubscriptionWorkerConfig
{
Enabled = true,
IsOrdered = true,
},
}
};
Mock<IDomainEventHandlerResolver> deh = new Mock<IDomainEventHandlerResolver>();
String eventStoreConnectionString = "esdb://192.168.0.133:2113?tls=true&tlsVerifyCert=false";
Dictionary<String, IDomainEventHandlerResolver> eventHandlerResolvers = new();
Action<TraceEventType, String, String> traceHandler = (et, type, msg) => { TestOutputHelper.WriteLine(msg); };
var result = IApplicationBuilderExtenstions.ConfigureSubscriptions(subscriptionRepository.Object, config,
eventStoreConnectionString, eventHandlerResolvers, traceHandler);
result.Count.ShouldBe(0);
}

[Fact]
public void ApplicationBuilderExtensions_ConfigureSubscriptions_MainOnlyWorkers_WorkerListReturned()
{
Mock<IApplicationBuilder> appBuilder = new Mock<IApplicationBuilder>();
Mock<ISubscriptionRepository> subscriptionRepository = new Mock<ISubscriptionRepository>();

SubscriptionWorkersRoot config = new SubscriptionWorkersRoot
{
SubscriptionWorkers = new List<SubscriptionWorkerConfig>
{
new SubscriptionWorkerConfig
{
Enabled = true,
IsOrdered = false,
InstanceCount = 1,
InflightMessages= 500
}
}
};
Mock<IDomainEventHandlerResolver> deh = new Mock<IDomainEventHandlerResolver>();
String eventStoreConnectionString = "esdb://192.168.0.133:2113?tls=true&tlsVerifyCert=false";
Dictionary<String, IDomainEventHandlerResolver> eventHandlerResolvers = new();
eventHandlerResolvers.Add("Main", deh.Object);
Action<TraceEventType, String, String> traceHandler = (et, type, msg) => { TestOutputHelper.WriteLine(msg); };
var result = IApplicationBuilderExtenstions.ConfigureSubscriptions(subscriptionRepository.Object, config,
eventStoreConnectionString, eventHandlerResolvers, traceHandler);
result.Count.ShouldBe(1);
result.Single().InflightMessages.ShouldBe(500);
}

[Fact]
public void ApplicationBuilderExtensions_ConfigureSubscriptions_MainOnlyWorkers_NoHandlers_WorkerListReturned()
{
Mock<IApplicationBuilder> appBuilder = new Mock<IApplicationBuilder>();
Mock<ISubscriptionRepository> subscriptionRepository = new Mock<ISubscriptionRepository>();

SubscriptionWorkersRoot config = new SubscriptionWorkersRoot
{
SubscriptionWorkers = new List<SubscriptionWorkerConfig>
{
new SubscriptionWorkerConfig
{
Enabled = true,
IsOrdered = false,
InstanceCount = 1,
InflightMessages= 500
}
}
};
Mock<IDomainEventHandlerResolver> deh = new Mock<IDomainEventHandlerResolver>();
String eventStoreConnectionString = "esdb://192.168.0.133:2113?tls=true&tlsVerifyCert=false";
Dictionary<String, IDomainEventHandlerResolver> eventHandlerResolvers = new();
Action<TraceEventType, String, String> traceHandler = (et, type, msg) => { TestOutputHelper.WriteLine(msg); };
var result = IApplicationBuilderExtenstions.ConfigureSubscriptions(subscriptionRepository.Object, config,
eventStoreConnectionString, eventHandlerResolvers, traceHandler);
result.Count.ShouldBe(0);
}

[Fact]
public void ApplicationBuilderExtensions_ConfigureSubscriptions_MainOnlyWorkers_InstanceCount2_WorkerListReturned()
{
Mock<IApplicationBuilder> appBuilder = new Mock<IApplicationBuilder>();
Mock<ISubscriptionRepository> subscriptionRepository = new Mock<ISubscriptionRepository>();

SubscriptionWorkersRoot config = new SubscriptionWorkersRoot
{
SubscriptionWorkers = new List<SubscriptionWorkerConfig>
{
new SubscriptionWorkerConfig
{
Enabled = true,
IsOrdered = false,
InstanceCount = 2,
InflightMessages= 500
}
}
};
Mock<IDomainEventHandlerResolver> deh = new Mock<IDomainEventHandlerResolver>();
String eventStoreConnectionString = "esdb://192.168.0.133:2113?tls=true&tlsVerifyCert=false";
Dictionary<String, IDomainEventHandlerResolver> eventHandlerResolvers = new();
eventHandlerResolvers.Add("Main", deh.Object);
Action<TraceEventType, String, String> traceHandler = (et, type, msg) => { TestOutputHelper.WriteLine(msg); };
Func<String, Int32, ISubscriptionRepository> subscriptionRepositoryResolver = (s, i) => { return subscriptionRepository.Object; };
var result = IApplicationBuilderExtenstions.ConfigureSubscriptions(subscriptionRepository.Object, config,
eventStoreConnectionString, eventHandlerResolvers, traceHandler);
result.Count.ShouldBe(2);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
namespace Shared.EventStore.Tests;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Moq;
using Shouldly;
using SimpleResults;

namespace Shared.EventStore.Tests;

using Extensions;
using global::EventStore.Client;
using Microsoft.Extensions.DependencyInjection;
using Pose;
using Shared.EventStore.EventStore;
using System;
using TestObjects;
using Xunit;

Expand All @@ -13,4 +24,58 @@ public void AddEventStore_HealthCheckAdded(){
IHealthChecksBuilder builder = new TestHealthChecksBuilder();
builder.AddEventStore(new EventStoreClientSettings(), null, null, null);
}
}

public class EventStoreConnectionStringHealthCheckTests {
[Fact]
public async Task EventStoreConnectionStringHealthCheck_CheckHealthAsync_EventsReturned_Healthy() {
Mock<IEventStoreContext> context = new Mock<IEventStoreContext>();
AggregateNameSetEvent aggregateNameSetEvent = new AggregateNameSetEvent(TestData.AggregateId, TestData.EventId, "Test");

EventRecord r = TestData.CreateEventRecord<AggregateNameSetEvent>(aggregateNameSetEvent, "TestAggregate");

var resolvedEvent = new ResolvedEvent(r, null,null);

context.Setup(c => c.ReadLastEventsFromAll(It.IsAny<long>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(new List<ResolvedEvent>() { resolvedEvent }));
EventStoreConnectionStringHealthCheck healthCheck = new EventStoreConnectionStringHealthCheck(context.Object);
var result = await healthCheck.CheckHealthAsync(new HealthCheckContext(), CancellationToken.None);
result.Status.ShouldBe(HealthStatus.Healthy);
}

[Fact]
public async Task EventStoreConnectionStringHealthCheck_CheckHealthAsync_NoEventsReturned_Unhealthy()
{
Mock<IEventStoreContext> context = new Mock<IEventStoreContext>();
AggregateNameSetEvent aggregateNameSetEvent = new AggregateNameSetEvent(TestData.AggregateId, TestData.EventId, "Test");

context.Setup(c => c.ReadLastEventsFromAll(It.IsAny<long>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Success(new List<ResolvedEvent>()));
EventStoreConnectionStringHealthCheck healthCheck = new EventStoreConnectionStringHealthCheck(context.Object);
var result = await healthCheck.CheckHealthAsync(new HealthCheckContext(), CancellationToken.None);
result.Status.ShouldBe(HealthStatus.Unhealthy);
}

[Fact]
public async Task EventStoreConnectionStringHealthCheck_CheckHealthAsync_ReadLastEventsFromAll_Unhealthy()
{
Mock<IEventStoreContext> context = new Mock<IEventStoreContext>();
AggregateNameSetEvent aggregateNameSetEvent = new AggregateNameSetEvent(TestData.AggregateId, TestData.EventId, "Test");

context.Setup(c => c.ReadLastEventsFromAll(It.IsAny<long>(), It.IsAny<CancellationToken>())).ReturnsAsync(Result.Failure());
EventStoreConnectionStringHealthCheck healthCheck = new EventStoreConnectionStringHealthCheck(context.Object);
var result = await healthCheck.CheckHealthAsync(new HealthCheckContext(), CancellationToken.None);
result.Status.ShouldBe(HealthStatus.Unhealthy);
}

[Fact]
public async Task EventStoreConnectionStringHealthCheck_CheckHealthAsync_ExceptionThrown_Unhealthy()
{
Mock<IEventStoreContext> context = new Mock<IEventStoreContext>();
AggregateNameSetEvent aggregateNameSetEvent = new AggregateNameSetEvent(TestData.AggregateId, TestData.EventId, "Test");

context.Setup(c => c.ReadLastEventsFromAll(It.IsAny<long>(), It.IsAny<CancellationToken>())).ThrowsAsync(new Exception());
EventStoreConnectionStringHealthCheck healthCheck = new EventStoreConnectionStringHealthCheck(context.Object);

var result = await healthCheck.CheckHealthAsync(new HealthCheckContext(), CancellationToken.None);
result.Status.ShouldBe(HealthStatus.Unhealthy);
}
}
3 changes: 2 additions & 1 deletion Shared.EventStore.Tests/Shared.EventStore.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<DebugType>None</DebugType>
<DebugType>Full</DebugType>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand All @@ -18,6 +18,7 @@
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="Pose" Version="1.2.1" />
<PackageReference Include="Shouldly" Version="4.2.1" />
<PackageReference Include="xunit" Version="2.7.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
Expand Down
Loading