-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add EventStore Hosting and Client integrations #277
Changes from 17 commits
f543c2b
5da0502
259b29b
bb12675
6843bd9
a8b8066
ebd5908
8998861
2daf3c8
1d93d6c
65a034b
a3c762f
bae8ad2
7cad08f
d0c35a0
8553d6f
6a1b859
9fc57ec
90fceff
58f537c
61d2676
396fe02
20e91bf
cdae698
282d122
8011a92
30f10e9
0ff0242
d9c770b
f0d33f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
using Aspire.Components.Common.Tests; | ||
using Aspire.Hosting; | ||
using Aspire.Hosting.Utils; | ||
using CommunityToolkit.Aspire.Testing; | ||
using EventStore.Client; | ||
using Microsoft.Extensions.Diagnostics.HealthChecks; | ||
using Microsoft.Extensions.Hosting; | ||
|
@@ -20,17 +19,17 @@ public class EventStoreFunctionalTests(ITestOutputHelper testOutputHelper) | |
[Fact] | ||
public async Task VerifyEventStoreResource() | ||
{ | ||
using var builder = TestDistributedApplicationBuilder.Create(testOutputHelper); | ||
using var builder = TestDistributedApplicationBuilder.Create().WithTestAndResourceLogging(testOutputHelper); | ||
|
||
var eventstore = builder.AddEventStore("eventstore"); | ||
|
||
using var app = builder.Build(); | ||
|
||
await app.StartAsync(); | ||
|
||
#pragma warning disable CTASPIRE001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | ||
await app.WaitForTextAsync("Processor ConnectorsStreamSupervisor Running", "eventstore"); | ||
#pragma warning restore CTASPIRE001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | ||
var rns = app.Services.GetRequiredService<ResourceNotificationService>(); | ||
|
||
await rns.WaitForResourceHealthyAsync(eventstore.Resource.Name, default); | ||
|
||
var hostBuilder = Host.CreateApplicationBuilder(); | ||
|
||
|
@@ -44,7 +43,8 @@ public async Task VerifyEventStoreResource() | |
|
||
var eventStoreClient = host.Services.GetRequiredService<EventStoreClient>(); | ||
|
||
await CreateTestData(eventStoreClient); | ||
var id = await CreateTestDataAsync(eventStoreClient); | ||
await VerifyTestDataAsync(eventStoreClient, id); | ||
} | ||
|
||
[Theory] | ||
|
@@ -58,8 +58,7 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) | |
|
||
try | ||
{ | ||
using var builder1 = TestDistributedApplicationBuilder.Create(testOutputHelper); | ||
|
||
using var builder1 = TestDistributedApplicationBuilder.Create().WithTestAndResourceLogging(testOutputHelper); | ||
var eventstore1 = builder1.AddEventStore("eventstore"); | ||
|
||
if (useVolume) | ||
|
@@ -76,16 +75,28 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) | |
else | ||
{ | ||
bindMountPath = Directory.CreateTempSubdirectory().FullName; | ||
|
||
if (!OperatingSystem.IsWindows()) | ||
{ | ||
// Change permissions for non-root accounts (container user account) | ||
const UnixFileMode OwnershipPermissions = | ||
UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute | | ||
UnixFileMode.GroupRead | UnixFileMode.GroupWrite | UnixFileMode.GroupExecute | | ||
UnixFileMode.OtherRead | UnixFileMode.OtherWrite | UnixFileMode.OtherExecute; | ||
|
||
File.SetUnixFileMode(bindMountPath, OwnershipPermissions); | ||
} | ||
|
||
eventstore1.WithDataBindMount(bindMountPath); | ||
} | ||
|
||
using (var app = builder1.Build()) | ||
{ | ||
await app.StartAsync(); | ||
|
||
#pragma warning disable CTASPIRE001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | ||
await app.WaitForTextAsync("Processor ConnectorsStreamSupervisor Running", eventstore1.Resource.Name); | ||
#pragma warning restore CTASPIRE001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | ||
var rns = app.Services.GetRequiredService<ResourceNotificationService>(); | ||
|
||
await rns.WaitForResourceHealthyAsync(eventstore1.Resource.Name, default); | ||
|
||
try | ||
{ | ||
|
@@ -100,7 +111,8 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) | |
await host.StartAsync(); | ||
|
||
var eventStoreClient = host.Services.GetRequiredService<EventStoreClient>(); | ||
id = await CreateTestData(eventStoreClient); | ||
id = await CreateTestDataAsync(eventStoreClient); | ||
await VerifyTestDataAsync(eventStoreClient, id.Value); | ||
} | ||
} | ||
finally | ||
|
@@ -110,8 +122,7 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) | |
} | ||
} | ||
|
||
using var builder2 = TestDistributedApplicationBuilder.Create(testOutputHelper); | ||
|
||
using var builder2 = TestDistributedApplicationBuilder.Create().WithTestAndResourceLogging(testOutputHelper); | ||
var eventstore2 = builder2.AddEventStore("eventstore"); | ||
|
||
if (useVolume) | ||
|
@@ -120,16 +131,18 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) | |
} | ||
else | ||
{ | ||
//EventStore shutdown can be slightly delayed, so second instance might fail to start when using the same bind mount before shutdown. | ||
await Task.Delay(TimeSpan.FromSeconds(5)); | ||
eventstore2.WithDataBindMount(bindMountPath!); | ||
} | ||
|
||
using (var app = builder2.Build()) | ||
{ | ||
await app.StartAsync(); | ||
|
||
#pragma warning disable CTASPIRE001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | ||
await app.WaitForTextAsync("Processor ConnectorsStreamSupervisor Running", eventstore2.Resource.Name); | ||
#pragma warning restore CTASPIRE001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. | ||
var rns = app.Services.GetRequiredService<ResourceNotificationService>(); | ||
|
||
await rns.WaitForResourceHealthyAsync(eventstore1.Resource.Name, default); | ||
|
||
try | ||
{ | ||
|
@@ -144,7 +157,7 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) | |
await host.StartAsync(); | ||
var eventStoreClient = host.Services.GetRequiredService<EventStoreClient>(); | ||
|
||
await VerifyTestData(eventStoreClient, id.Value); | ||
await VerifyTestDataAsync(eventStoreClient, id.Value); | ||
} | ||
} | ||
finally | ||
|
@@ -179,8 +192,8 @@ public async Task WithDataShouldPersistStateBetweenUsages(bool useVolume) | |
[Fact] | ||
public async Task VerifyWaitForEventStoreBlocksDependentResources() | ||
{ | ||
var cts = new CancellationTokenSource(TimeSpan.FromMinutes(10)); | ||
using var builder = TestDistributedApplicationBuilder.Create(testOutputHelper); | ||
var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5)); | ||
using var builder = TestDistributedApplicationBuilder.Create().WithTestAndResourceLogging(testOutputHelper); | ||
|
||
var healthCheckTcs = new TaskCompletionSource<HealthCheckResult>(); | ||
builder.Services.AddHealthChecks().AddAsyncCheck("blocking_check", () => | ||
|
@@ -191,7 +204,7 @@ public async Task VerifyWaitForEventStoreBlocksDependentResources() | |
var resource = builder.AddEventStore("resource") | ||
.WithHealthCheck("blocking_check"); | ||
|
||
var dependentResource = builder.AddEventStore("dependentresource") | ||
var dependentResource = builder.AddContainer("nginx", "mcr.microsoft.com/cbl-mariner/base/nginx", "1.22") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a light (meaning small image size and fast startup) container image? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly, I used this specifically because it's lightweight and fast to start. |
||
.WaitFor(resource); | ||
|
||
using var app = builder.Build(); | ||
|
@@ -206,7 +219,7 @@ public async Task VerifyWaitForEventStoreBlocksDependentResources() | |
|
||
healthCheckTcs.SetResult(HealthCheckResult.Healthy()); | ||
|
||
await rns.WaitForResourceAsync(resource.Resource.Name, re => re.Snapshot.HealthStatus == HealthStatus.Healthy, cts.Token); | ||
await rns.WaitForResourceHealthyAsync(resource.Resource.Name, cts.Token); | ||
|
||
await rns.WaitForResourceAsync(dependentResource.Resource.Name, KnownResourceStates.Running, cts.Token); | ||
|
||
|
@@ -215,7 +228,7 @@ public async Task VerifyWaitForEventStoreBlocksDependentResources() | |
await app.StopAsync(); | ||
} | ||
|
||
private static async Task<Guid> CreateTestData(EventStoreClient eventStoreClient) | ||
private static async Task<Guid> CreateTestDataAsync(EventStoreClient eventStoreClient) | ||
{ | ||
var id = Guid.NewGuid(); | ||
var accountCreated = new AccountCreated(id, TestAccountName); | ||
|
@@ -226,12 +239,10 @@ private static async Task<Guid> CreateTestData(EventStoreClient eventStoreClient | |
var writeResult = await eventStoreClient.AppendToStreamAsync(streamName, StreamRevision.None, [eventData]); | ||
Assert.NotNull(writeResult); | ||
|
||
await VerifyTestData(eventStoreClient, id); | ||
|
||
return id; | ||
} | ||
|
||
private static async Task VerifyTestData(EventStoreClient eventStoreClient, Guid id) | ||
private static async Task VerifyTestDataAsync(EventStoreClient eventStoreClient, Guid id) | ||
{ | ||
var streamName = $"{TestStreamNamePrefix}{id}"; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could incur flakiness.
Related dotnet/aspire#4878