diff --git a/.github/workflows/pull-request-docs.yml b/.github/workflows/pull-request-docs.yml
index a28ed530d..420b55e3a 100644
--- a/.github/workflows/pull-request-docs.yml
+++ b/.github/workflows/pull-request-docs.yml
@@ -9,6 +9,11 @@ jobs:
docs:
runs-on: ubuntu-latest
steps:
+ -
+ name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
-
name: Checkout
uses: actions/checkout@v4
@@ -16,5 +21,5 @@ jobs:
name: Build docs
run: |
cd docs
- yarn install
- yarn build
+ pnpm install
+ pnpm build
diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml
index 29a7d81da..91de2b1d8 100644
--- a/.github/workflows/pull-request.yml
+++ b/.github/workflows/pull-request.yml
@@ -18,9 +18,6 @@ jobs:
build-and-test:
name: "Build and test"
runs-on: ubuntu-latest
- strategy:
- matrix:
- dotnet: [ 'net6.0', 'net8.0' ]
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
TC_CLOUD_TOKEN: ${{ secrets.TC_TOKEN }}
@@ -32,11 +29,14 @@ jobs:
name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: '8.0'
+ dotnet-version: |
+ 8.0.x
+ 9.0.x
+ dotnet-quality: 'preview'
-
name: Build
run: |
- dotnet build -c "Debug CI" -f ${{ matrix.dotnet }}
+ dotnet build -c "Debug CI"
-
name: Prepare Testcontainers Cloud agent
if: env.TC_CLOUD_TOKEN != ''
@@ -44,7 +44,7 @@ jobs:
-
name: Run tests
run: |
- dotnet test -c "Debug CI" --no-build -f ${{ matrix.dotnet }}
+ dotnet test -c "Debug CI" --no-build
-
name: Upload Test Results
if: always()
diff --git a/Directory.Packages.props b/Directory.Packages.props
index af2b1b4dd..064af7c8d 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -1,104 +1,106 @@
-
- true
-
-
- 8.0
- 8.0.6
-
-
- [6.0.5,7)
- 2.3.0
-
-
- 8.0.6
- 3.0.0
-
-
- 3.9.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ true
+
+
+ 9.0.0-rc.2.24474.3
+ 9.0.0-rc.2.24473.5
+ 9.0.0-rc.2.24474.3
+
+
+ 8.0.6
+ 8.0
+ 8.0.8
+
+
+ 3.10.0
+
+
+ 8.0.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Eventuous.sln b/Eventuous.sln
index 634def5f0..3668bfbb7 100644
--- a/Eventuous.sln
+++ b/Eventuous.sln
@@ -163,8 +163,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Diagnostics", "sr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Application", "src\Core\src\Eventuous.Application\Eventuous.Application.csproj", "{3743969A-4635-40DE-B45C-46F80CBB5733}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Tests.Diagnostics", "src\Core\test\Eventuous.Tests.Diagnostics\Eventuous.Tests.Diagnostics.csproj", "{EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Tests.Application", "src\Core\test\Eventuous.Tests.Application\Eventuous.Tests.Application.csproj", "{2C44A145-81E5-4F43-9C9A-AB3CF822AF82}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Redis", "src\Redis\src\Eventuous.Redis\Eventuous.Redis.csproj", "{179C730A-CD2E-4B4D-935B-38F7E9CFE33B}"
@@ -213,10 +211,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bookings.Payments", "sample
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bookings", "samples\esdb\Bookings\Bookings.csproj", "{C666D8E7-FB55-4435-A8D4-CF9815660E85}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Tests.Persistence", "src\Core\test\Eventuous.Tests.Persistence\Eventuous.Tests.Persistence.csproj", "{F24F066B-FC7A-4298-B007-19CC86BB31E1}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Brokers", "Brokers", "{86D92758-EBB6-4B8C-94B7-BD91AF1E31D2}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Extensions.Logging", "src\Extensions\src\Eventuous.Extensions.Logging\Eventuous.Extensions.Logging.csproj", "{E1F6CDD8-D37E-487B-A429-25A06C590FE4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.TestHelpers.TUnit", "test\Eventuous.TestHelpers.TUnit\Eventuous.TestHelpers.TUnit.csproj", "{2A816CFD-5D05-4F64-8222-F7214B229EBC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -474,12 +474,6 @@ Global
{3743969A-4635-40DE-B45C-46F80CBB5733}.Release|Any CPU.Build.0 = Release|Any CPU
{3743969A-4635-40DE-B45C-46F80CBB5733}.Debug CI|Any CPU.ActiveCfg = Debug CI|Any CPU
{3743969A-4635-40DE-B45C-46F80CBB5733}.Debug CI|Any CPU.Build.0 = Debug CI|Any CPU
- {EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9}.Release|Any CPU.Build.0 = Release|Any CPU
- {EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9}.Debug CI|Any CPU.ActiveCfg = Debug CI|Any CPU
- {EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9}.Debug CI|Any CPU.Build.0 = Debug CI|Any CPU
{2C44A145-81E5-4F43-9C9A-AB3CF822AF82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2C44A145-81E5-4F43-9C9A-AB3CF822AF82}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C44A145-81E5-4F43-9C9A-AB3CF822AF82}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -552,12 +546,18 @@ Global
{C666D8E7-FB55-4435-A8D4-CF9815660E85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C666D8E7-FB55-4435-A8D4-CF9815660E85}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C666D8E7-FB55-4435-A8D4-CF9815660E85}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F24F066B-FC7A-4298-B007-19CC86BB31E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F24F066B-FC7A-4298-B007-19CC86BB31E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F24F066B-FC7A-4298-B007-19CC86BB31E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F24F066B-FC7A-4298-B007-19CC86BB31E1}.Release|Any CPU.Build.0 = Release|Any CPU
- {F24F066B-FC7A-4298-B007-19CC86BB31E1}.Debug CI|Any CPU.ActiveCfg = Debug CI|Any CPU
- {F24F066B-FC7A-4298-B007-19CC86BB31E1}.Debug CI|Any CPU.Build.0 = Debug CI|Any CPU
+ {E1F6CDD8-D37E-487B-A429-25A06C590FE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E1F6CDD8-D37E-487B-A429-25A06C590FE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E1F6CDD8-D37E-487B-A429-25A06C590FE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E1F6CDD8-D37E-487B-A429-25A06C590FE4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E1F6CDD8-D37E-487B-A429-25A06C590FE4}.Debug CI|Any CPU.ActiveCfg = Debug CI|Any CPU
+ {E1F6CDD8-D37E-487B-A429-25A06C590FE4}.Debug CI|Any CPU.Build.0 = Debug CI|Any CPU
+ {2A816CFD-5D05-4F64-8222-F7214B229EBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2A816CFD-5D05-4F64-8222-F7214B229EBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2A816CFD-5D05-4F64-8222-F7214B229EBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2A816CFD-5D05-4F64-8222-F7214B229EBC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2A816CFD-5D05-4F64-8222-F7214B229EBC}.Debug CI|Any CPU.ActiveCfg = Debug CI|Any CPU
+ {2A816CFD-5D05-4F64-8222-F7214B229EBC}.Debug CI|Any CPU.Build.0 = Debug CI|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -629,7 +629,6 @@ Global
{8B155B20-B23E-490E-85B8-9712BCA91F04} = {7BBD9F8E-EB6A-4E2D-84A9-AF15C1784401}
{A25D6B10-5B40-46B2-ACBB-F47C76ECFAB8} = {7BBD9F8E-EB6A-4E2D-84A9-AF15C1784401}
{3743969A-4635-40DE-B45C-46F80CBB5733} = {7BBD9F8E-EB6A-4E2D-84A9-AF15C1784401}
- {EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9} = {0ED6785B-60EF-46B4-B938-EF04189FC8BC}
{2C44A145-81E5-4F43-9C9A-AB3CF822AF82} = {0ED6785B-60EF-46B4-B938-EF04189FC8BC}
{179C730A-CD2E-4B4D-935B-38F7E9CFE33B} = {0E2520E7-B4A6-47E7-AED8-662C88441A84}
{5DACCAF8-9CD4-4B0B-96B7-15EF049EB199} = {B1AAD6CA-2710-41E0-9495-B43C313D6BCA}
@@ -653,10 +652,11 @@ Global
{7D86A33D-7C1A-45F7-BEFF-1B95525716D6} = {75F337AF-7E15-4ED1-8E4F-A582DABEA373}
{7D24DAB3-FD49-443C-811A-96F0CA6A6F9A} = {75F337AF-7E15-4ED1-8E4F-A582DABEA373}
{C666D8E7-FB55-4435-A8D4-CF9815660E85} = {75F337AF-7E15-4ED1-8E4F-A582DABEA373}
- {F24F066B-FC7A-4298-B007-19CC86BB31E1} = {0ED6785B-60EF-46B4-B938-EF04189FC8BC}
{1970CA0D-C5E8-4384-8485-82D712289002} = {86D92758-EBB6-4B8C-94B7-BD91AF1E31D2}
{6E545DFE-FE70-4486-92E0-E47E86E66210} = {86D92758-EBB6-4B8C-94B7-BD91AF1E31D2}
{2E59C5F8-3E5A-4450-B902-7648AD7ECC0F} = {86D92758-EBB6-4B8C-94B7-BD91AF1E31D2}
+ {E1F6CDD8-D37E-487B-A429-25A06C590FE4} = {2B7F84B7-C0E5-408F-ABAF-BF23C8305486}
+ {2A816CFD-5D05-4F64-8222-F7214B229EBC} = {C60C6094-2A03-45B6-AB33-C514C35DF823}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0691467B-C257-46DB-BC4F-88EB7CD615B8}
diff --git a/docs/package.json b/docs/package.json
index 90c9baaca..2869ffdee 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -46,7 +46,7 @@
]
},
"engines": {
- "node": ">=16.14"
+ "node": ">=18.19.0"
},
"packageManager": "pnpm@9.10.0"
}
diff --git a/docs/versioned_docs/version-0.15/application/command-api.md b/docs/versioned_docs/version-0.15/application/command-api.md
index 921bc2ba9..6331f6a6e 100644
--- a/docs/versioned_docs/version-0.15/application/command-api.md
+++ b/docs/versioned_docs/version-0.15/application/command-api.md
@@ -24,7 +24,7 @@ Here is an example of a command API controller:
```csharp
[Route("/booking")]
-public class CommandApi(ICommandService service)
+public class CommandApi(ICommandService service)
: CommandHttpApiBase {
[HttpPost]
[Route("book")]
diff --git a/props/Common.props b/props/Common.props
new file mode 100644
index 000000000..2d45cd706
--- /dev/null
+++ b/props/Common.props
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props
index 53ba4c935..da955ecae 100644
--- a/samples/Directory.Build.props
+++ b/samples/Directory.Build.props
@@ -10,4 +10,5 @@
$(RepoRoot)\src
Debug;Release
+
\ No newline at end of file
diff --git a/samples/esdb/Bookings.Payments/Bookings.Payments.csproj b/samples/esdb/Bookings.Payments/Bookings.Payments.csproj
index c3758e9f8..aa9f8bed0 100644
--- a/samples/esdb/Bookings.Payments/Bookings.Payments.csproj
+++ b/samples/esdb/Bookings.Payments/Bookings.Payments.csproj
@@ -1,32 +1,32 @@
-
- Debug;Release
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- PreserveNewest
- PreserveNewest
-
-
-
-
-
-
-
-
-
-
+
+ Debug;Release
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ PreserveNewest
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/esdb/Bookings.Payments/Program.cs b/samples/esdb/Bookings.Payments/Program.cs
index e8075f99e..f2679abe2 100644
--- a/samples/esdb/Bookings.Payments/Program.cs
+++ b/samples/esdb/Bookings.Payments/Program.cs
@@ -19,7 +19,7 @@
builder.Host.UseSerilog();
var app = builder.Build();
-app.UseEventuousLogs();
+app.Services.AddEventuousLogs();
app.UseSwagger();
app.UseOpenTelemetryPrometheusScrapingEndpoint();
diff --git a/samples/esdb/Bookings/Bookings.csproj b/samples/esdb/Bookings/Bookings.csproj
index b77713ee3..1aaebe78f 100644
--- a/samples/esdb/Bookings/Bookings.csproj
+++ b/samples/esdb/Bookings/Bookings.csproj
@@ -1,39 +1,39 @@
-
- Linux
- Debug;Release
- AnyCPU
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- PreserveNewest
-
-
+
+ Linux
+ Debug;Release
+ AnyCPU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ PreserveNewest
+
+
\ No newline at end of file
diff --git a/samples/esdb/Bookings/Registrations.cs b/samples/esdb/Bookings/Registrations.cs
index 3c4f79f46..35f524952 100644
--- a/samples/esdb/Bookings/Registrations.cs
+++ b/samples/esdb/Bookings/Registrations.cs
@@ -11,6 +11,7 @@
using Eventuous.EventStore.Subscriptions;
using Eventuous.Projections.MongoDB;
using Eventuous.Subscriptions.Registrations;
+using MongoDB.Driver.Core.Extensions.DiagnosticSources;
using NodaTime;
using NodaTime.Serialization.SystemTextJson;
using OpenTelemetry.Metrics;
@@ -76,7 +77,7 @@ public static void AddTelemetry(this IServiceCollection services) {
.AddAspNetCoreInstrumentation()
.AddGrpcClientInstrumentation()
.AddEventuousTracing()
- .AddMongoDBInstrumentation()
+ .AddSource(typeof(DiagnosticsActivityEventSubscriber).Assembly.GetName().Name!)
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("bookings"))
.SetSampler(new AlwaysOnSampler());
diff --git a/samples/postgres/Bookings.Payments/Bookings.Payments.csproj b/samples/postgres/Bookings.Payments/Bookings.Payments.csproj
index b19b7048b..2447ff1b2 100644
--- a/samples/postgres/Bookings.Payments/Bookings.Payments.csproj
+++ b/samples/postgres/Bookings.Payments/Bookings.Payments.csproj
@@ -5,7 +5,8 @@
-
+
+
@@ -33,7 +34,7 @@
-
+
diff --git a/samples/postgres/Bookings.Payments/Program.cs b/samples/postgres/Bookings.Payments/Program.cs
index 4b0e16263..92c29e128 100644
--- a/samples/postgres/Bookings.Payments/Program.cs
+++ b/samples/postgres/Bookings.Payments/Program.cs
@@ -20,7 +20,7 @@
var app = builder.Build();
-app.UseEventuousLogs();
+app.Services.AddEventuousLogs();
app.UseSwagger().UseSwaggerUI();
app.UseOpenTelemetryPrometheusScrapingEndpoint();
diff --git a/samples/postgres/Bookings/Bookings.csproj b/samples/postgres/Bookings/Bookings.csproj
index ec6a13e80..413f971ad 100644
--- a/samples/postgres/Bookings/Bookings.csproj
+++ b/samples/postgres/Bookings/Bookings.csproj
@@ -1,34 +1,34 @@
-
- Linux
- Debug;Release
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ Linux
+ Debug;Release
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/postgres/Bookings/Infrastructure/Mongo.cs b/samples/postgres/Bookings/Infrastructure/Mongo.cs
index d10633e1c..400375d6d 100644
--- a/samples/postgres/Bookings/Infrastructure/Mongo.cs
+++ b/samples/postgres/Bookings/Infrastructure/Mongo.cs
@@ -12,14 +12,11 @@ public static IMongoDatabase ConfigureMongo(IConfiguration configuration) {
var settings = MongoClientSettings.FromConnectionString(config.ConnectionString);
if (config is { User: not null, Password: not null }) {
- settings.Credential = new MongoCredential(
- null,
- new MongoInternalIdentity("admin", config.User),
- new PasswordEvidence(config.Password)
- );
+ settings.Credential = new(null, new MongoInternalIdentity("admin", config.User), new PasswordEvidence(config.Password));
}
settings.ClusterConfigurator = cb => cb.Subscribe(new DiagnosticsActivityEventSubscriber());
+
return new MongoClient(settings).GetDatabase(config.Database);
}
diff --git a/samples/postgres/Bookings/Infrastructure/Telemetry.cs b/samples/postgres/Bookings/Infrastructure/Telemetry.cs
index 02b4ec22f..d2069283f 100644
--- a/samples/postgres/Bookings/Infrastructure/Telemetry.cs
+++ b/samples/postgres/Bookings/Infrastructure/Telemetry.cs
@@ -1,4 +1,5 @@
using Eventuous.Diagnostics.OpenTelemetry;
+using MongoDB.Driver.Core.Extensions.DiagnosticSources;
using Npgsql;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
@@ -30,7 +31,7 @@ public static void AddTelemetry(this IServiceCollection services) {
.AddAspNetCoreInstrumentation()
.AddEventuousTracing()
.AddNpgsql()
- .AddMongoDBInstrumentation();
+ .AddSource(typeof(DiagnosticsActivityEventSubscriber).Assembly.GetName().Name!);
if (otelEnabled)
builder.AddOtlpExporter();
diff --git a/src/Core/src/Eventuous.Persistence/AggregateFactory.cs b/src/Core/src/Eventuous.Persistence/AggregateFactory.cs
index 440b9549a..82a8d6909 100644
--- a/src/Core/src/Eventuous.Persistence/AggregateFactory.cs
+++ b/src/Core/src/Eventuous.Persistence/AggregateFactory.cs
@@ -12,6 +12,15 @@ public class AggregateFactoryRegistry {
/// Aggregate factory registry singleton instance
///
public static readonly AggregateFactoryRegistry Instance = new();
+
+ private AggregateFactoryRegistry() { }
+
+ [UsedImplicitly]
+ public AggregateFactoryRegistry(IServiceProvider sp, IEnumerable resolvers) {
+ foreach (var resolver in resolvers) {
+ UnsafeCreateAggregateUsing(resolver.Type, () => resolver.CreateInstance(sp));
+ }
+ }
internal readonly Dictionary> Registry = new();
@@ -39,3 +48,5 @@ public AggregateFactoryRegistry CreateAggregateUsing(AggregateFactory
}
public delegate T AggregateFactory() where T : Aggregate where TState : State, new();
+
+public record ResolveAggregateFactory(Type Type, Func CreateInstance);
diff --git a/src/Core/src/Eventuous.Producers/Diagnostics/ProducerEventSource.cs b/src/Core/src/Eventuous.Producers/Diagnostics/ProducerEventSource.cs
index 24d5404a6..ea5b5b313 100644
--- a/src/Core/src/Eventuous.Producers/Diagnostics/ProducerEventSource.cs
+++ b/src/Core/src/Eventuous.Producers/Diagnostics/ProducerEventSource.cs
@@ -20,7 +20,7 @@ public class ProducerEventSource : EventSource where T : class {
[NonEvent]
public void ProduceAcknowledged(ProducedMessage message) {
if (IsEnabled(EventLevel.Verbose, EventKeywords.All)) {
- ProduceAcknowledged(ProducerName, message);
+ ProduceAcknowledged(ProducerName, message.GetType().Name);
}
}
@@ -29,14 +29,14 @@ public void ProduceNotAcknowledged(ProducedMessage message, string error, Except
if (!IsEnabled(EventLevel.Verbose, EventKeywords.All)) return;
var errorMessage = $"{error} {e?.Message}";
- ProduceNotAcknowledged(ProducerName, message, errorMessage);
+ ProduceNotAcknowledged(ProducerName, message.GetType().Name, errorMessage);
}
[Event(ProduceAcknowledgedId, Level = EventLevel.Verbose, Message = "[{0}] Produce acknowledged: {1}")]
- void ProduceAcknowledged(string producer, object message)
- => WriteEvent(ProduceAcknowledgedId, producer, message.GetType().Name);
+ void ProduceAcknowledged(string producer, string messageType)
+ => WriteEvent(ProduceAcknowledgedId, producer, messageType);
[Event(ProduceNotAcknowledgedId, Level = EventLevel.Verbose, Message = "[{0}] Produce not acknowledged: {1} {2}")]
- void ProduceNotAcknowledged(string producer, object message, string error)
- => WriteEvent(ProduceNotAcknowledgedId, producer, message.GetType().Name, error);
+ void ProduceNotAcknowledged(string producer, string messageType, string error)
+ => WriteEvent(ProduceNotAcknowledgedId, producer, messageType, error);
}
\ No newline at end of file
diff --git a/src/Core/src/Eventuous.Subscriptions/Checkpoints/CheckpointCommitHandler.cs b/src/Core/src/Eventuous.Subscriptions/Checkpoints/CheckpointCommitHandler.cs
index 0fcf1500e..678356ff7 100644
--- a/src/Core/src/Eventuous.Subscriptions/Checkpoints/CheckpointCommitHandler.cs
+++ b/src/Core/src/Eventuous.Subscriptions/Checkpoints/CheckpointCommitHandler.cs
@@ -79,7 +79,7 @@ async ValueTask Process(CommitPosition[] list, CancellationToken cancellationTok
[PublicAPI]
public ValueTask Commit(CommitPosition position, CancellationToken cancellationToken) {
if (Diagnostic.IsEnabled(CommitOperation)) Diagnostic.Write(CommitOperation, new CommitEvent(_subscriptionId, position, _positions.Min));
- position.LogContext.PositionReceived(position);
+ position.LogContext?.PositionReceived(position);
return _worker.Write(position, cancellationToken);
}
@@ -124,7 +124,7 @@ async Task CommitInternal(CommitPosition position, bool force, CancellationToken
return;
}
- position.LogContext.CommittingPosition(position);
+ position.LogContext?.CommittingPosition(position);
await _commitCheckpoint(new(_subscriptionId, position.Position), force, cancellationToken).NoContext();
_lastCommit = position;
_positions.RemoveWhere(x => x.Sequence <= position.Sequence);
@@ -132,7 +132,7 @@ async Task CommitInternal(CommitPosition position, bool force, CancellationToken
await _commitCheckpoint(new(_subscriptionId, position.Position), true, default).NoContext();
_positions.RemoveWhere(x => x.Sequence <= position.Sequence);
} catch (Exception e) {
- position.LogContext.UnableToCommitPosition(position, e);
+ position.LogContext?.UnableToCommitPosition(position, e);
}
}
@@ -149,7 +149,7 @@ public async ValueTask DisposeAsync() {
public readonly record struct CommitPosition(ulong Position, ulong Sequence, DateTime Timestamp) {
public bool Valid { get; private init; } = true;
- public LogContext LogContext { get; init; }
+ public LogContext? LogContext { get; init; }
public static readonly CommitPosition None = new(0, 0, DateTime.MinValue) { Valid = false };
diff --git a/src/Core/src/Eventuous.Subscriptions/Registrations/SubscriptionBuilderExtensions.cs b/src/Core/src/Eventuous.Subscriptions/Registrations/SubscriptionBuilderExtensions.cs
index a9e346d2f..8667b5000 100644
--- a/src/Core/src/Eventuous.Subscriptions/Registrations/SubscriptionBuilderExtensions.cs
+++ b/src/Core/src/Eventuous.Subscriptions/Registrations/SubscriptionBuilderExtensions.cs
@@ -42,8 +42,7 @@ public static SubscriptionBuilder WithPartitioningByStream(this SubscriptionBuil
/// Subscription options type
/// Checkpoint store type
///
- public static SubscriptionBuilder UseCheckpointStore
- (this SubscriptionBuilder builder)
+ public static SubscriptionBuilder UseCheckpointStore(this SubscriptionBuilder builder)
where T : class, ICheckpointStore
where TSubscription : EventSubscriptionWithCheckpoint
where TOptions : SubscriptionWithCheckpointOptions {
diff --git a/src/Core/test/Eventuous.Tests.Application/CommandServiceTests.cs b/src/Core/test/Eventuous.Tests.Application/CommandServiceTests.cs
index 6b37ced91..a6c3dfe7e 100644
--- a/src/Core/test/Eventuous.Tests.Application/CommandServiceTests.cs
+++ b/src/Core/test/Eventuous.Tests.Application/CommandServiceTests.cs
@@ -4,7 +4,8 @@
namespace Eventuous.Tests.Application;
// ReSharper disable once UnusedType.Global
-public class CommandServiceTests(ITestOutputHelper output) : ServiceTestBase(output) {
+[InheritsTests]
+public class CommandServiceTests : ServiceTestBase {
protected override ICommandService CreateService(
AmendEvent? amendEvent = null,
AmendEvent? amendAll = null
diff --git a/src/Core/test/Eventuous.Tests.Application/Eventuous.Tests.Application.csproj b/src/Core/test/Eventuous.Tests.Application/Eventuous.Tests.Application.csproj
index c46c553b7..024226d4a 100644
--- a/src/Core/test/Eventuous.Tests.Application/Eventuous.Tests.Application.csproj
+++ b/src/Core/test/Eventuous.Tests.Application/Eventuous.Tests.Application.csproj
@@ -2,13 +2,25 @@
true
true
+ Exe
+ true
+
ServiceTestBase.cs
+
+ ServiceTestBase.cs
+
+
+ ServiceTestBase.cs
+
+
+ ServiceTestBase.cs
+
diff --git a/src/Core/test/Eventuous.Tests.Application/FunctionalServiceTests.cs b/src/Core/test/Eventuous.Tests.Application/FunctionalServiceTests.cs
index 7462f9b81..df45d3021 100644
--- a/src/Core/test/Eventuous.Tests.Application/FunctionalServiceTests.cs
+++ b/src/Core/test/Eventuous.Tests.Application/FunctionalServiceTests.cs
@@ -5,7 +5,8 @@ namespace Eventuous.Tests.Application;
using Sut.Domain;
// ReSharper disable once UnusedType.Global
-public class FunctionalServiceTests(ITestOutputHelper output) : ServiceTestBase(output) {
+[InheritsTests]
+public class FunctionalServiceTests() : ServiceTestBase() {
protected override ICommandService CreateService(
AmendEvent? amendEvent = null,
AmendEvent? amendAll = null
diff --git a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.Amendments.cs b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.Amendments.cs
index d51bb415a..09db048a0 100644
--- a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.Amendments.cs
+++ b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.Amendments.cs
@@ -4,18 +4,18 @@
namespace Eventuous.Tests.Application;
public abstract partial class ServiceTestBase {
- [Fact]
- public async Task Should_amend_event_from_command() {
+ [Test]
+ public async Task Should_amend_event_from_command(CancellationToken cancellationToken) {
var service = CreateService(amendEvent: AmendEvent);
var cmd = CreateCommand();
- await service.Handle(cmd, default);
+ await service.Handle(cmd, cancellationToken);
- var stream = await Store.ReadStream(StreamName.For(cmd.BookingId), StreamReadPosition.Start);
+ var stream = await Store.ReadStream(StreamName.For(cmd.BookingId), StreamReadPosition.Start, cancellationToken: cancellationToken);
stream[0].Metadata["userId"].Should().Be(cmd.ImportedBy);
}
- [Fact]
+ [Test]
public async Task Should_amend_event_with_static_meta() {
var cmd = Helpers.GetBookRoom();
@@ -26,14 +26,14 @@ await CommandServiceFixture
.Then(x => x.StreamIs(e => e[0].Metadata["foo"].Should().Be("bar")));
}
- [Fact]
- public async Task Should_combine_amendments() {
+ [Test]
+ public async Task Should_combine_amendments(CancellationToken cancellationToken) {
var service = CreateService(amendEvent: AmendEvent, amendAll: AddMeta);
var cmd = CreateCommand();
- await service.Handle(cmd, default);
+ await service.Handle(cmd, cancellationToken);
- var stream = await Store.ReadStream(StreamName.For(cmd.BookingId), StreamReadPosition.Start);
+ var stream = await Store.ReadStream(StreamName.For(cmd.BookingId), StreamReadPosition.Start, cancellationToken: cancellationToken);
stream[0].Metadata["userId"].Should().Be(cmd.ImportedBy);
stream[0].Metadata["foo"].Should().Be("bar");
}
diff --git a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnAny.cs b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnAny.cs
index 7c4890c45..1eac4e8ff 100644
--- a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnAny.cs
+++ b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnAny.cs
@@ -5,7 +5,7 @@
namespace Eventuous.Tests.Application;
public abstract partial class ServiceTestBase {
- [Fact]
+ [Test]
public async Task Should_execute_on_any_no_stream() {
var bookRoom = Helpers.GetBookRoom();
diff --git a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnExisting.cs b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnExisting.cs
index 7a28f51c6..26aa7e8f2 100644
--- a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnExisting.cs
+++ b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnExisting.cs
@@ -6,7 +6,7 @@
namespace Eventuous.Tests.Application;
public abstract partial class ServiceTestBase {
- [Fact]
+ [Test]
public async Task Should_execute_on_existing_stream_exists() {
var seedCmd = Helpers.GetBookRoom();
var seed = new BookingEvents.RoomBooked(seedCmd.RoomId, seedCmd.CheckIn, seedCmd.CheckOut, seedCmd.Price);
@@ -27,7 +27,7 @@ await CommandServiceFixture
.Then(result => result.ResultIsOk().NewStreamEventsAre(expectedResult));
}
- [Fact]
+ [Test]
public async Task Should_fail_on_existing_no_stream() {
var seedCmd = Helpers.GetBookRoom();
var paymentTime = DateTimeOffset.Now;
diff --git a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnNew.cs b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnNew.cs
index c2ae68116..3731188ac 100644
--- a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnNew.cs
+++ b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.OnNew.cs
@@ -4,7 +4,7 @@
namespace Eventuous.Tests.Application;
public abstract partial class ServiceTestBase {
- [Fact]
+ [Test]
public async Task Should_run_on_new_no_stream() {
var cmd = Helpers.GetBookRoom();
var expected = new BookingEvents.RoomBooked(cmd.RoomId, cmd.CheckIn, cmd.CheckOut, cmd.Price);
@@ -16,7 +16,7 @@ await CommandServiceFixture
.Then(result => result.ResultIsOk(x => x.Changes.Should().HaveCount(1)).FullStreamEventsAre(expected));
}
- [Fact]
+ [Test]
public async Task Should_fail_on_new_stream_exists() {
var cmd = Helpers.GetBookRoom();
var seed = new BookingEvents.RoomBooked(cmd.RoomId, cmd.CheckIn, cmd.CheckOut, cmd.Price);
diff --git a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.cs b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.cs
index 2d2319a49..534613798 100644
--- a/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.cs
+++ b/src/Core/test/Eventuous.Tests.Application/ServiceTestBase.cs
@@ -1,22 +1,22 @@
using Eventuous.Sut.App;
using Eventuous.Sut.Domain;
-using Eventuous.TestHelpers;
+using Eventuous.TestHelpers.TUnit;
using Eventuous.Testing;
using NodaTime;
using static Eventuous.Sut.Domain.BookingEvents;
namespace Eventuous.Tests.Application;
-public abstract partial class ServiceTestBase : IDisposable {
- [Fact]
- public async Task Ensure_builder_is_thread_safe() {
+public abstract partial class ServiceTestBase {
+ [Test]
+ public async Task Ensure_builder_is_thread_safe(CancellationToken cancellationToken) {
const int threadCount = 3;
var service = CreateService();
var tasks = Enumerable
.Range(1, threadCount)
- .Select(bookingId => Task.Run(() => service.Handle(Helpers.GetBookRoom(bookingId.ToString()), default)))
+ .Select(bookingId => Task.Run(() => service.Handle(Helpers.GetBookRoom(bookingId.ToString()), cancellationToken)))
.ToList();
await Task.WhenAll(tasks);
@@ -42,8 +42,8 @@ static ImportBooking CreateCommand() {
return cmd;
}
- protected ServiceTestBase(ITestOutputHelper output) {
- _listener = new(output);
+ protected ServiceTestBase() {
+ _listener = new();
TypeMap.RegisterKnownEventTypes(typeof(RoomBooked).Assembly);
}
@@ -66,5 +66,6 @@ protected record ImportBooking(
string ImportedBy
);
+ [After(Test)]
public void Dispose() => _listener.Dispose();
}
diff --git a/src/Core/test/Eventuous.Tests.Application/StateWithIdTests.cs b/src/Core/test/Eventuous.Tests.Application/StateWithIdTests.cs
index 0b55c3ad7..bd9e9028d 100644
--- a/src/Core/test/Eventuous.Tests.Application/StateWithIdTests.cs
+++ b/src/Core/test/Eventuous.Tests.Application/StateWithIdTests.cs
@@ -12,8 +12,8 @@ public class StateWithIdTests {
public StateWithIdTests() => _service = new(_store);
- [Fact]
- public async Task ShouldGetIdForNew() {
+ [Test]
+ public async Task ShouldGetIdForNew(CancellationToken cancellationToken) {
var map = new StreamNameMap();
var id = Guid.NewGuid().ToString();
var result = await Seed(id);
@@ -24,7 +24,7 @@ public async Task ShouldGetIdForNew() {
result.TryGet(out var ok).Should().BeTrue();
ok!.State.Id.Should().Be(bookingId);
- var instance = await _store.LoadAggregate(bookingId, map, true);
+ var instance = await _store.LoadAggregate(bookingId, map, true, cancellationToken: cancellationToken);
// Ensure that the id was set when the aggregate was loaded
instance.State.Id.Should().Be(bookingId);
diff --git a/src/Core/test/Eventuous.Tests.Diagnostics/Eventuous.Tests.Diagnostics.csproj b/src/Core/test/Eventuous.Tests.Diagnostics/Eventuous.Tests.Diagnostics.csproj
deleted file mode 100644
index 1d616f398..000000000
--- a/src/Core/test/Eventuous.Tests.Diagnostics/Eventuous.Tests.Diagnostics.csproj
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- true
- true
-
-
diff --git a/src/Core/test/Eventuous.Tests.Persistence.Base/Eventuous.Tests.Persistence.Base.csproj b/src/Core/test/Eventuous.Tests.Persistence.Base/Eventuous.Tests.Persistence.Base.csproj
index dc4de2531..20223ed8d 100644
--- a/src/Core/test/Eventuous.Tests.Persistence.Base/Eventuous.Tests.Persistence.Base.csproj
+++ b/src/Core/test/Eventuous.Tests.Persistence.Base/Eventuous.Tests.Persistence.Base.csproj
@@ -1,16 +1,22 @@
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
+
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/DomainFixture.cs b/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/DomainFixture.cs
index f68362ce3..5483f9560 100644
--- a/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/DomainFixture.cs
+++ b/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/DomainFixture.cs
@@ -1,10 +1,11 @@
+using AutoFixture;
using Eventuous.Sut.App;
using NodaTime;
namespace Eventuous.Tests.Persistence.Base.Fixtures;
public static class DomainFixture {
- static DomainFixture() => TypeMap.RegisterKnownEventTypes();
+ static DomainFixture() => TypeMap.RegisterKnownEventTypes(typeof(DomainFixture).Assembly);
public static Commands.ImportBooking CreateImportBooking(IFixture auto) {
var from = auto.Create();
diff --git a/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/Helpers.cs b/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/Helpers.cs
index cd4e00e27..3a22e4c0a 100644
--- a/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/Helpers.cs
+++ b/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/Helpers.cs
@@ -1,3 +1,4 @@
+using AutoFixture;
using static Eventuous.Sut.App.Commands;
using static Eventuous.Sut.Domain.BookingEvents;
diff --git a/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/StoreFixtureBase.cs b/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/StoreFixtureBase.cs
index e380699be..2769af31b 100644
--- a/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/StoreFixtureBase.cs
+++ b/src/Core/test/Eventuous.Tests.Persistence.Base/Fixtures/StoreFixtureBase.cs
@@ -1,37 +1,35 @@
-// Copyright (C) Ubiquitous AS.All rights reserved
-// Licensed under the Apache License, Version 2.0.
-
using System.Text.RegularExpressions;
+using AutoFixture;
using Bogus;
using DotNet.Testcontainers.Containers;
using Eventuous.TestHelpers;
+using Eventuous.TestHelpers.TUnit.Logging;
using MicroElements.AutoFixture.NodaTime;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using TUnit.Core.Interfaces;
namespace Eventuous.Tests.Persistence.Base.Fixtures;
+public interface IStartableFixture : IAsyncInitializer, IAsyncDisposable;
+
public abstract class StoreFixtureBase {
- public IEventStore EventStore { get; protected private set; } = null!;
- public IFixture Auto { get; } = new Fixture().Customize(new NodaTimeCustomization());
- protected static Faker Faker { get; } = new();
- protected ServiceProvider Provider { get; set; } = null!;
- protected bool AutoStart { get; init; } = true;
- public ITestOutputHelper? Output { get; set; }
- public TypeMapper TypeMapper { get; } = new();
+ public IEventStore EventStore { get; protected private set; } = null!;
+ public IFixture Auto { get; } = new Fixture().Customize(new NodaTimeCustomization());
+ protected static Faker Faker { get; } = new();
+ protected ServiceProvider Provider { get; set; } = null!;
+ protected bool AutoStart { get; init; } = true;
+ public TypeMapper TypeMapper { get; } = new();
}
-public abstract partial class StoreFixtureBase : StoreFixtureBase, IAsyncLifetime where TContainer : DockerContainer {
+public abstract partial class StoreFixtureBase : StoreFixtureBase, IStartableFixture where TContainer : DockerContainer {
public virtual async Task InitializeAsync() {
Container = CreateContainer();
await Container.StartAsync();
var services = new ServiceCollection();
- if (Output != null) {
- services.AddSingleton(Output);
- services.AddLogging(cfg => cfg.AddXunit(Output, LogLevel.Debug).SetMinimumLevel(LogLevel.Debug));
- }
+ services.AddLogging(cfg => cfg.ForTests());
Serializer = new DefaultEventSerializer(TestPrimitives.DefaultOptions, TypeMapper);
services.AddSingleton(Serializer);
@@ -55,7 +53,7 @@ protected async Task Start() {
}
}
- public virtual async Task DisposeAsync() {
+ public virtual async ValueTask DisposeAsync() {
if (_disposed) return;
_disposed = true;
diff --git a/src/Core/test/Eventuous.Tests.Persistence.Base/Store/Append.cs b/src/Core/test/Eventuous.Tests.Persistence.Base/Store/Append.cs
index 42fd41ff3..aa353d71b 100644
--- a/src/Core/test/Eventuous.Tests.Persistence.Base/Store/Append.cs
+++ b/src/Core/test/Eventuous.Tests.Persistence.Base/Store/Append.cs
@@ -6,7 +6,7 @@
namespace Eventuous.Tests.Persistence.Base.Store;
-public abstract class StoreAppendTests : IClassFixture where T : StoreFixtureBase {
+public abstract class StoreAppendTests where T : StoreFixtureBase {
readonly T _fixture;
protected StoreAppendTests(T fixture) {
@@ -14,18 +14,18 @@ protected StoreAppendTests(T fixture) {
_fixture = fixture;
}
- [Fact]
- [Trait("Category", "Store")]
+ [Test]
+ [Category("Store")]
public async Task ShouldAppendToNoStream() {
var evt = _fixture.CreateEvent();
var streamName = _fixture.GetStreamName();
var result = await _fixture.AppendEvent(streamName, evt, ExpectedStreamVersion.NoStream);
- result.NextExpectedVersion.Should().Be(0);
+ await Assert.That(result.NextExpectedVersion).IsEqualTo(0);
}
- [Fact]
- [Trait("Category", "Store")]
+ [Test]
+ [Category("Store")]
public async Task ShouldAppendOneByOne() {
var evt = _fixture.CreateEvent();
var stream = _fixture.GetStreamName();
@@ -37,11 +37,11 @@ public async Task ShouldAppendOneByOne() {
var version = new ExpectedStreamVersion(result.NextExpectedVersion);
result = await _fixture.AppendEvent(stream, evt, version);
- result.NextExpectedVersion.Should().Be(1);
+ await Assert.That(result.NextExpectedVersion).IsEqualTo(1);
}
- [Fact]
- [Trait("Category", "Store")]
+ [Test]
+ [Category("Store")]
public async Task ShouldFailOnWrongVersionNoStream() {
var evt = _fixture.CreateEvent();
var stream = _fixture.GetStreamName();
@@ -50,12 +50,11 @@ public async Task ShouldFailOnWrongVersionNoStream() {
evt = _fixture.CreateEvent();
- var task = () => _fixture.AppendEvent(stream, evt, ExpectedStreamVersion.NoStream);
- await task.Should().ThrowAsync();
+ await Assert.That(() => _fixture.AppendEvent(stream, evt, ExpectedStreamVersion.NoStream)).Throws();
}
- [Fact]
- [Trait("Category", "Store")]
+ [Test]
+ [Category("Store")]
public async Task ShouldFailOnWrongVersion() {
var evt = _fixture.CreateEvent();
var stream = _fixture.GetStreamName();
@@ -64,13 +63,12 @@ public async Task ShouldFailOnWrongVersion() {
evt = _fixture.CreateEvent();
- var task = () => _fixture.AppendEvent(stream, evt, new(3));
- await task.Should().ThrowAsync();
+ await Assert.That(() => _fixture.AppendEvent(stream, evt, new(3))).Throws();
}
- [Fact]
- [Trait("Category", "Store")]
+ [Test]
+ [Category("Store")]
public async Task ShouldFailOnWrongVersionWithOptimisticConcurrencyException() {
var evt = _fixture.CreateEvent();
var stream = _fixture.GetStreamName();
@@ -79,7 +77,6 @@ public async Task ShouldFailOnWrongVersionWithOptimisticConcurrencyException() {
evt = _fixture.CreateEvent();
- var task = () => _fixture.StoreChanges(stream, evt, new(3));
- await task.Should().ThrowAsync();
+ await Assert.That(() => _fixture.StoreChanges(stream, evt, new(3))).Throws();
}
}
diff --git a/src/Core/test/Eventuous.Tests.Persistence.Base/Store/OtherMethods.cs b/src/Core/test/Eventuous.Tests.Persistence.Base/Store/OtherMethods.cs
index 06e871685..439885867 100644
--- a/src/Core/test/Eventuous.Tests.Persistence.Base/Store/OtherMethods.cs
+++ b/src/Core/test/Eventuous.Tests.Persistence.Base/Store/OtherMethods.cs
@@ -3,7 +3,7 @@
namespace Eventuous.Tests.Persistence.Base.Store;
-public abstract class StoreOtherOpsTests : IClassFixture where T : StoreFixtureBase {
+public abstract class StoreOtherOpsTests where T : StoreFixtureBase {
readonly T _fixture;
protected StoreOtherOpsTests(T fixture) {
@@ -11,22 +11,22 @@ protected StoreOtherOpsTests(T fixture) {
fixture.TypeMapper.RegisterKnownEventTypes(typeof(BookingEvents.BookingImported).Assembly);
}
- [Fact]
- [Trait("Category", "Store")]
- public async Task StreamShouldExist() {
+ [Test]
+ [Category("Store")]
+ public async Task StreamShouldExist(CancellationToken cancellationToken) {
var evt = _fixture.CreateEvent();
var streamName = _fixture.GetStreamName();
await _fixture.AppendEvent(streamName, evt, ExpectedStreamVersion.NoStream);
- var exists = await _fixture.EventStore.StreamExists(streamName, default);
- exists.Should().BeTrue();
+ var exists = await _fixture.EventStore.StreamExists(streamName, cancellationToken);
+ await Assert.That(exists).IsTrue();
}
- [Fact]
- [Trait("Category", "Store")]
- public async Task StreamShouldNotExist() {
+ [Test]
+ [Category("Store")]
+ public async Task StreamShouldNotExist(CancellationToken cancellationToken) {
var streamName = _fixture.GetStreamName();
- var exists = await _fixture.EventStore.StreamExists(streamName, default);
- exists.Should().BeFalse();
+ var exists = await _fixture.EventStore.StreamExists(streamName, cancellationToken);
+ await Assert.That(exists).IsFalse();
}
}
diff --git a/src/Core/test/Eventuous.Tests.Persistence.Base/Store/Read.cs b/src/Core/test/Eventuous.Tests.Persistence.Base/Store/Read.cs
index 06cdbf1c4..45e5ce2d2 100644
--- a/src/Core/test/Eventuous.Tests.Persistence.Base/Store/Read.cs
+++ b/src/Core/test/Eventuous.Tests.Persistence.Base/Store/Read.cs
@@ -6,7 +6,7 @@
namespace Eventuous.Tests.Persistence.Base.Store;
-public abstract class StoreReadTests : IClassFixture where T : StoreFixtureBase {
+public abstract class StoreReadTests where T : StoreFixtureBase {
readonly T _fixture;
protected StoreReadTests(T fixture) {
@@ -14,72 +14,71 @@ protected StoreReadTests(T fixture) {
_fixture = fixture;
}
- [Fact]
- [Trait("Category", "Store")]
- public async Task ShouldReadOne() {
+ [Test]
+ [Category("Store")]
+ public async Task ShouldReadOne(CancellationToken cancellationToken) {
var evt = _fixture.CreateEvent();
var streamName = _fixture.GetStreamName();
await _fixture.AppendEvent(streamName, evt, ExpectedStreamVersion.NoStream);
- var result = await _fixture.EventStore.ReadEvents(streamName, StreamReadPosition.Start, 100, default);
- result.Length.Should().Be(1);
- result[0].Payload.Should().BeEquivalentTo(evt);
+ var result = await _fixture.EventStore.ReadEvents(streamName, StreamReadPosition.Start, 100, cancellationToken);
+ await Assert.That(result.Length).IsEqualTo(1);
+ await Assert.That(result[0].Payload).IsEquivalentTo(evt);
}
- [Fact]
- [Trait("Category", "Store")]
- public async Task ShouldReadMany() {
+ [Test]
+ [Category("Store")]
+ public async Task ShouldReadMany(CancellationToken cancellationToken) {
object[] events = _fixture.CreateEvents(20).ToArray();
var streamName = _fixture.GetStreamName();
await _fixture.AppendEvents(streamName, events, ExpectedStreamVersion.NoStream);
- var result = await _fixture.EventStore.ReadEvents(streamName, StreamReadPosition.Start, 100, default);
+ var result = await _fixture.EventStore.ReadEvents(streamName, StreamReadPosition.Start, 100, cancellationToken);
var actual = result.Select(x => x.Payload);
- actual.Should().BeEquivalentTo(events);
+ await Assert.That(actual).IsEquivalentTo(events);
}
- [Fact]
- [Trait("Category", "Store")]
- public async Task ShouldReadTail() {
+ [Test]
+ [Category("Store")]
+ public async Task ShouldReadTail(CancellationToken cancellationToken) {
object[] events = _fixture.CreateEvents(20).ToArray();
var streamName = _fixture.GetStreamName();
await _fixture.AppendEvents(streamName, events, ExpectedStreamVersion.NoStream);
- var result = await _fixture.EventStore.ReadEvents(streamName, new(10), 100, default);
+ var result = await _fixture.EventStore.ReadEvents(streamName, new(10), 100, cancellationToken);
var expected = events.Skip(10);
var actual = result.Select(x => x.Payload);
- actual.Should().BeEquivalentTo(expected);
+ await Assert.That(actual).IsEquivalentTo(expected);
}
- [Fact]
- [Trait("Category", "Store")]
- public async Task ShouldReadHead() {
+ [Test]
+ [Category("Store")]
+ public async Task ShouldReadHead(CancellationToken cancellationToken) {
object[] events = _fixture.CreateEvents(20).ToArray();
var streamName = _fixture.GetStreamName();
await _fixture.AppendEvents(streamName, events, ExpectedStreamVersion.NoStream);
- var result = await _fixture.EventStore.ReadEvents(streamName, StreamReadPosition.Start, 10, default);
+ var result = await _fixture.EventStore.ReadEvents(streamName, StreamReadPosition.Start, 10, cancellationToken);
var expected = events.Take(10);
- var actual = result.Select(x => x.Payload);
- actual.Should().BeEquivalentTo(expected);
+
+ IEnumerable
+
+
+
diff --git a/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/SubscriptionExtensions.cs b/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/SubscriptionExtensions.cs
index 25af43ffb..16edd47ae 100644
--- a/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/SubscriptionExtensions.cs
+++ b/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/SubscriptionExtensions.cs
@@ -1,18 +1,19 @@
using Eventuous.Subscriptions;
+using Microsoft.Extensions.Logging;
namespace Eventuous.Tests.Subscriptions.Base;
public static class SubscriptionExtensions {
- public static ValueTask SubscribeWithLog(this IMessageSubscription subscription, ILogger log)
+ public static ValueTask SubscribeWithLog(this IMessageSubscription subscription, ILogger log, CancellationToken cancellationToken = default)
=> subscription.Subscribe(
id => log.LogInformation("{Subscription} subscribed", id),
(id, reason, ex) => log.LogWarning(ex, "{Subscription} dropped {Reason}", id, reason),
- CancellationToken.None
+ cancellationToken
);
- public static ValueTask UnsubscribeWithLog(this IMessageSubscription subscription, ILogger log)
+ public static ValueTask UnsubscribeWithLog(this IMessageSubscription subscription, ILogger log, CancellationToken cancellationToken = default)
=> subscription.Unsubscribe(
id => log.LogInformation("{Subscription} unsubscribed", id),
- CancellationToken.None
+ cancellationToken
);
}
\ No newline at end of file
diff --git a/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/SubscriptionFixtureBase.cs b/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/SubscriptionFixtureBase.cs
index 5c5534895..96f34f43c 100644
--- a/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/SubscriptionFixtureBase.cs
+++ b/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/SubscriptionFixtureBase.cs
@@ -2,31 +2,29 @@
using Eventuous.Subscriptions;
using Eventuous.Subscriptions.Checkpoints;
using Eventuous.Sut.Domain;
+using Eventuous.TestHelpers.TUnit.Logging;
using Eventuous.Tests.Persistence.Base.Fixtures;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using ILogger = Microsoft.Extensions.Logging.ILogger;
+using LogLevel = Microsoft.Extensions.Logging.LogLevel;
namespace Eventuous.Tests.Subscriptions.Base;
public abstract class SubscriptionFixtureBase
- : StoreFixtureBase
+ : StoreFixtureBase, IStartableFixture
where TEventHandler : class, IEventHandler
where TContainer : DockerContainer
where TCheckpointStore : class, ICheckpointStore
where TSubscription : EventSubscription
where TSubscriptionOptions : SubscriptionOptions {
- readonly ITestOutputHelper _outputHelper;
- readonly bool _autoStart;
- readonly LogLevel _logLevel;
-
- protected SubscriptionFixtureBase(
- ITestOutputHelper outputHelper,
- bool autoStart = true,
- LogLevel logLevel = LogLevel.Trace
- ) {
- _outputHelper = outputHelper;
- _autoStart = autoStart;
- _logLevel = logLevel;
+ readonly bool _autoStart;
+ readonly LogLevel _logLevel;
+
+ protected SubscriptionFixtureBase(bool autoStart = true, LogLevel logLevel = LogLevel.Trace) {
+ _autoStart = autoStart;
+ _logLevel = logLevel;
TypeMapper.RegisterKnownEventTypes(typeof(BookingEvents.BookingImported).Assembly);
}
@@ -63,7 +61,7 @@ protected override void SetupServices(IServiceCollection services) {
var host = services.First(x => !x.IsKeyedService && x.ImplementationFactory?.GetType() == typeof(Func));
services.Remove(host);
- services.AddLogging(b => ConfigureLogging(b.AddXunit(_outputHelper, _logLevel).SetMinimumLevel(_logLevel)));
+ services.AddLogging(b => ConfigureLogging(b.ForTests(_logLevel)));
}
protected override void GetDependencies(IServiceProvider provider) {
@@ -85,7 +83,7 @@ public override async Task InitializeAsync() {
if (_autoStart) await StartSubscription();
}
- public override async Task DisposeAsync() {
+ public override async ValueTask DisposeAsync() {
if (_autoStart) await StopSubscription();
await base.DisposeAsync();
}
diff --git a/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/TestEventHandler.cs b/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/TestEventHandler.cs
index 0f3f0f9b5..8f0e29762 100644
--- a/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/TestEventHandler.cs
+++ b/src/Core/test/Eventuous.Tests.Subscriptions.Base/Fixtures/TestEventHandler.cs
@@ -2,7 +2,9 @@
using Eventuous.Subscriptions.Context;
using Hypothesist;
using Hypothesist.Builders;
+
// ReSharper disable NotAccessedPositionalProperty.Global
+// ReSharper disable MethodHasAsyncOverload
namespace Eventuous.Tests.Subscriptions.Base;
@@ -12,7 +14,9 @@ public record TestEvent(string Data, int Number) {
public const string TypeName = "test-event";
}
-public class TestEventHandler(TestEventHandlerOptions? options = null) : BaseEventHandler {
+public class TestEventHandler(TestEventHandlerOptions? options) : BaseEventHandler {
+ public TestEventHandler() : this(null) { }
+
readonly TimeSpan _delay = options?.Delay ?? TimeSpan.Zero;
public int Count { get; private set; }
@@ -25,7 +29,7 @@ public Hypothesis