diff --git a/.github/workflows/base.yml b/.github/workflows/base.yml index 43d5ce4c5..27a82d347 100644 --- a/.github/workflows/base.yml +++ b/.github/workflows/base.yml @@ -15,9 +15,6 @@ on: required: false type: string default: eventstore-ce/eventstoredb-ce -# test: -# required: true -# type: string jobs: test: @@ -25,11 +22,10 @@ jobs: strategy: fail-fast: false matrix: - framework: [ net9.0 ] + framework: [ net8.0, net9.0 ] os: [ ubuntu-latest ] configuration: [ release ] runs-on: ${{ matrix.os }} -# name: ${{ inputs.test }} (${{ matrix.os }}, ${{ matrix.framework }}) name: (${{ matrix.os }}, ${{ matrix.framework }}) env: CLOUDSMITH_CICD_USER: ${{ secrets.CLOUDSMITH_CICD_USER }} @@ -66,10 +62,3 @@ jobs: --logger:"GitHubActions;report-warnings=false" --logger:"console;verbosity=normal" \ --framework ${{ matrix.framework }} \ test/Kurrent.Client.Tests - -# run: | -# sudo ./gencert.sh -# dotnet test --configuration ${{ matrix.configuration }} --blame \ -# --logger:"GitHubActions;report-warnings=false" --logger:"console;verbosity=normal" \ -# --framework ${{ matrix.framework }} \ -# test/EventStore.Client.${{ inputs.test }}.Tests diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f408ae3c..5b659d1fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,14 +14,11 @@ jobs: strategy: fail-fast: false matrix: -# docker-tag: [ ci, lts, previous-lts ] - docker-tag: [ ci ] -# test: [ Streams, PersistentSubscriptions, Operations, UserManagement, ProjectionManagement ] + docker-tag: [ ci, lts, previous-lts ] name: Test CE (${{ matrix.docker-tag }}) with: docker-tag: ${{ matrix.docker-tag }} docker-image: eventstore-ce/eventstoredb-ce -# test: ${{ matrix.test }} # ee: # uses: ./.github/workflows/base.yml # if: ${{ github.repository_owner == 'EventStore' }} diff --git a/test/Kurrent.Client.Tests.Common/Fixtures/KurrentPermanentFixture.cs b/test/Kurrent.Client.Tests.Common/Fixtures/KurrentPermanentFixture.cs index c5da8c280..8e9f5bf56 100644 --- a/test/Kurrent.Client.Tests.Common/Fixtures/KurrentPermanentFixture.cs +++ b/test/Kurrent.Client.Tests.Common/Fixtures/KurrentPermanentFixture.cs @@ -87,7 +87,7 @@ public async Task InitializeAsync() { await ContainerSemaphore.WaitAsync(); try { await Service.Start(); - EventStoreVersion = GetEventStoreVersion(); + EventStoreVersion = GetKurrentVersion(); EventStoreHasLastStreamPosition = (EventStoreVersion?.Major ?? int.MaxValue) >= 21; // EventStoreHasLastStreamPosition = true; } finally { @@ -133,7 +133,7 @@ async Task InitClient(Func action, bool execute = true) where T : return client; } - static Version GetEventStoreVersion() { + static Version GetKurrentVersion() { const string versionPrefix = "EventStoreDB version"; using var cancellator = new CancellationTokenSource(FromSeconds(30)); @@ -146,8 +146,7 @@ static Version GetEventStoreVersion() { using var log = eventstore.Logs(true, cancellator.Token); foreach (var line in log.ReadToEnd()) { - Logger.Warning("line---> {line}", line); - + Logger.Information("EventStoreDB: {Line}", line); if (line.StartsWith(versionPrefix) && Version.TryParse( new string(ReadVersion(line[(versionPrefix.Length + 1)..]).ToArray()), diff --git a/test/Kurrent.Client.Tests.Common/Fixtures/KurrentPermanentTestNode.cs b/test/Kurrent.Client.Tests.Common/Fixtures/KurrentPermanentTestNode.cs index e8c554f02..b93bc9f89 100644 --- a/test/Kurrent.Client.Tests.Common/Fixtures/KurrentPermanentTestNode.cs +++ b/test/Kurrent.Client.Tests.Common/Fixtures/KurrentPermanentTestNode.cs @@ -189,7 +189,7 @@ async Task GetNextAvailablePort(TimeSpan delay = default) { #if NET if (socket.Connected) await socket.DisconnectAsync(true); #else - if (socket.Connected) socket.Disconnect(true); + if (socket.Connected) socket.Disconnect(true); #endif } } diff --git a/test/Kurrent.Client.Tests.Common/Fixtures/KurrentTemporaryFixture.cs b/test/Kurrent.Client.Tests.Common/Fixtures/KurrentTemporaryFixture.cs index 146808d20..3be5f5229 100644 --- a/test/Kurrent.Client.Tests.Common/Fixtures/KurrentTemporaryFixture.cs +++ b/test/Kurrent.Client.Tests.Common/Fixtures/KurrentTemporaryFixture.cs @@ -89,7 +89,7 @@ public async Task InitializeAsync() { await ContainerSemaphore.WaitAsync(); try { await Service.Start(); - EventStoreVersion = GetEventStoreVersion(); + EventStoreVersion = GetKurrentVersion(); EventStoreHasLastStreamPosition = (EventStoreVersion?.Major ?? int.MaxValue) >= 21; // EventStoreHasLastStreamPosition = true; } finally { @@ -135,7 +135,7 @@ async Task InitClient(Func action, bool execute = true) where T : return client; } - static Version GetEventStoreVersion() { + static Version GetKurrentVersion() { const string versionPrefix = "EventStoreDB version"; using var cancellator = new CancellationTokenSource(FromSeconds(30)); @@ -148,8 +148,7 @@ static Version GetEventStoreVersion() { using var log = eventstore.Logs(true, cancellator.Token); foreach (var line in log.ReadToEnd()) { - Logger.Warning("line---> {line}", line); - + Logger.Information("EventStoreDB: {Line}", line); if (line.StartsWith(versionPrefix) && Version.TryParse( new string(ReadVersion(line[(versionPrefix.Length + 1)..]).ToArray()), diff --git a/test/Kurrent.Client.Tests/Projections/DisableProjectionTests.cs b/test/Kurrent.Client.Tests/Projections/DisableProjectionTests.cs new file mode 100644 index 000000000..debe5d3db --- /dev/null +++ b/test/Kurrent.Client.Tests/Projections/DisableProjectionTests.cs @@ -0,0 +1,21 @@ +using Kurrent.Client.Tests.TestNode; + +namespace Kurrent.Client.Tests.Projections; + +public class DisableProjectionTests(ITestOutputHelper output, DisableProjectionTests.CustomFixture fixture) + : KurrentTemporaryTests(output, fixture) { + [Fact] + public async Task disable_projection() { + var name = Names.First(); + await Fixture.Projections.DisableAsync(name, userCredentials: TestCredentials.Root); + var result = await Fixture.Projections.GetStatusAsync(name, userCredentials: TestCredentials.Root); + Assert.NotNull(result); + Assert.Contains(["Aborted/Stopped", "Stopped"], x => x == result!.Status); + } + + static readonly string[] Names = ["$streams", "$stream_by_category", "$by_category", "$by_event_type", "$by_correlation_id"]; + + public class CustomFixture : KurrentTemporaryFixture { + public CustomFixture() : base(x => x.RunProjections()) { } + } +} diff --git a/test/Kurrent.Client.Tests/Projections/EnableProjectionTests.cs b/test/Kurrent.Client.Tests/Projections/EnableProjectionTests.cs new file mode 100644 index 000000000..26e49b972 --- /dev/null +++ b/test/Kurrent.Client.Tests/Projections/EnableProjectionTests.cs @@ -0,0 +1,21 @@ +using Kurrent.Client.Tests.TestNode; + +namespace Kurrent.Client.Tests.Projections; + +public class EnableProjectionTests(ITestOutputHelper output, EnableProjectionTests.CustomFixture fixture) + : KurrentTemporaryTests(output, fixture) { + [Fact] + public async Task enable_projection() { + var name = Names.First(); + await Fixture.Projections.EnableAsync(name, userCredentials: TestCredentials.Root); + var result = await Fixture.Projections.GetStatusAsync(name, userCredentials: TestCredentials.Root); + Assert.NotNull(result); + Assert.Equal("Running", result.Status); + } + + static readonly string[] Names = ["$streams", "$stream_by_category", "$by_category", "$by_event_type", "$by_correlation_id"]; + + public class CustomFixture : KurrentTemporaryFixture { + public CustomFixture() : base(x => x.RunProjections()) { } + } +} diff --git a/test/Kurrent.Client.Tests/Projections/GetProjectionResultTests.cs b/test/Kurrent.Client.Tests/Projections/GetProjectionResultTests.cs new file mode 100644 index 000000000..bf6ee80d9 --- /dev/null +++ b/test/Kurrent.Client.Tests/Projections/GetProjectionResultTests.cs @@ -0,0 +1,50 @@ +using EventStore.Client; +using Kurrent.Client.Tests.TestNode; + +namespace Kurrent.Client.Tests.Projections; + +public class GetProjectionResultTests(ITestOutputHelper output, GetProjectionResultTests.CustomFixture fixture) + : KurrentTemporaryTests(output, fixture) { + [Fact] + public async Task get_result() { + var name = Fixture.GetProjectionName(); + Result? result = null; + + var projection = $$""" + fromStream('{{name}}').when({ + "$init": function() { return { Count: 0 }; }, + "$any": function(s, e) { s.Count++; return s; } + }); + """; + + await Fixture.Projections.CreateContinuousAsync( + name, + projection, + userCredentials: TestCredentials.Root + ); + + await Fixture.Streams.AppendToStreamAsync( + name, + StreamState.NoStream, + Fixture.CreateTestEvents() + ); + + await AssertEx.IsOrBecomesTrue( + async () => { + result = await Fixture.Projections.GetResultAsync(name, userCredentials: TestCredentials.Root); + return result.Count > 0; + } + ); + + Assert.NotNull(result); + Assert.Equal(1, result!.Count); + } + + record Result { + public int Count { get; set; } + } + + public class CustomFixture : KurrentTemporaryFixture { + public CustomFixture() : base(x => x.RunProjections()) { } + } +} diff --git a/test/Kurrent.Client.Tests/Projections/GetProjectionStateTests.cs b/test/Kurrent.Client.Tests/Projections/GetProjectionStateTests.cs new file mode 100644 index 000000000..a762d97fd --- /dev/null +++ b/test/Kurrent.Client.Tests/Projections/GetProjectionStateTests.cs @@ -0,0 +1,51 @@ +using EventStore.Client; +using Kurrent.Client.Tests.TestNode; + +namespace Kurrent.Client.Tests.Projections; + +public class GetProjectionStateTests(ITestOutputHelper output, GetProjectionStateTests.CustomFixture fixture) + : KurrentTemporaryTests(output, fixture) { + [Fact] + public async Task get_state() { + var name = Fixture.GetProjectionName(); + + var projection = $$""" + fromStream('{{name}}').when({ + "$init": function() { return { Count: 0 }; }, + "$any": function(s, e) { s.Count++; return s; } + }); + """; + + Result? result = null; + + await Fixture.Projections.CreateContinuousAsync( + name, + projection, + userCredentials: TestCredentials.Root + ); + + await Fixture.Streams.AppendToStreamAsync( + name, + StreamState.NoStream, + Fixture.CreateTestEvents() + ); + + await AssertEx.IsOrBecomesTrue( + async () => { + result = await Fixture.Projections.GetStateAsync(name, userCredentials: TestCredentials.Root); + return result.Count > 0; + } + ); + + Assert.NotNull(result); + Assert.Equal(1, result!.Count); + } + + record Result { + public int Count { get; set; } + } + + public class CustomFixture : KurrentTemporaryFixture { + public CustomFixture() : base(x => x.RunProjections()) { } + } +} diff --git a/test/Kurrent.Client.Tests/Projections/GetProjectionStatusTests.cs b/test/Kurrent.Client.Tests/Projections/GetProjectionStatusTests.cs new file mode 100644 index 000000000..27d978eb0 --- /dev/null +++ b/test/Kurrent.Client.Tests/Projections/GetProjectionStatusTests.cs @@ -0,0 +1,21 @@ +using Kurrent.Client.Tests.TestNode; + +namespace Kurrent.Client.Tests.Projections; + +public class GetProjectionStatusTests(ITestOutputHelper output, GetProjectionStatusTests.CustomFixture fixture) + : KurrentTemporaryTests(output, fixture) { + [Fact] + public async Task get_status() { + var name = Names.First(); + var result = await Fixture.Projections.GetStatusAsync(name, userCredentials: TestCredentials.Root); + + Assert.NotNull(result); + Assert.Equal(name, result.Name); + } + + static readonly string[] Names = ["$streams", "$stream_by_category", "$by_category", "$by_event_type", "$by_correlation_id"]; + + public class CustomFixture : KurrentTemporaryFixture { + public CustomFixture() : base(x => x.RunProjections()) { } + } +} diff --git a/test/Kurrent.Client.Tests/Projections/ProjectionManagementTests.cs b/test/Kurrent.Client.Tests/Projections/ProjectionManagementTests.cs index 83b1a35cc..59c3f6b7a 100644 --- a/test/Kurrent.Client.Tests/Projections/ProjectionManagementTests.cs +++ b/test/Kurrent.Client.Tests/Projections/ProjectionManagementTests.cs @@ -1,7 +1,6 @@ // ReSharper disable InconsistentNaming // ReSharper disable ClassNeverInstantiated.Local -using EventStore.Client; using Kurrent.Client.Tests.TestNode; namespace Kurrent.Client.Tests; @@ -46,138 +45,8 @@ await Fixture.Projections.CreateTransientAsync( ); } - [Fact] - public async Task disable_projection() { - var name = Names.First(); - await Fixture.Projections.DisableAsync(name, userCredentials: TestCredentials.Root); - var result = await Fixture.Projections.GetStatusAsync(name, userCredentials: TestCredentials.Root); - Assert.NotNull(result); - Assert.Contains(["Aborted/Stopped", "Stopped"], x => x == result!.Status); - } - - [Fact] - public async Task enable_projection() { - var name = Names.First(); - await Fixture.Projections.EnableAsync(name, userCredentials: TestCredentials.Root); - var result = await Fixture.Projections.GetStatusAsync(name, userCredentials: TestCredentials.Root); - Assert.NotNull(result); - Assert.Equal("Running", result.Status); - } - - [Fact] - public async Task get_result() { - var name = Fixture.GetProjectionName(); - Result? result = null; - - var projection = $$""" - fromStream('{{name}}').when({ - "$init": function() { return { Count: 0 }; }, - "$any": function(s, e) { s.Count++; return s; } - }); - """; - - await Fixture.Projections.CreateContinuousAsync( - name, - projection, - userCredentials: TestCredentials.Root - ); - - await Fixture.Streams.AppendToStreamAsync( - name, - StreamState.NoStream, - Fixture.CreateTestEvents() - ); - - await AssertEx.IsOrBecomesTrue( - async () => { - result = await Fixture.Projections.GetResultAsync(name, userCredentials: TestCredentials.Root); - return result.Count > 0; - } - ); - - Assert.NotNull(result); - Assert.Equal(1, result!.Count); - } - - [Fact] - public async Task get_state() { - var name = Fixture.GetProjectionName(); - - var projection = $$""" - fromStream('{{name}}').when({ - "$init": function() { return { Count: 0 }; }, - "$any": function(s, e) { s.Count++; return s; } - }); - """; - - Result? result = null; - - await Fixture.Projections.CreateContinuousAsync( - name, - projection, - userCredentials: TestCredentials.Root - ); - - await Fixture.Streams.AppendToStreamAsync( - name, - StreamState.NoStream, - Fixture.CreateTestEvents() - ); - - await AssertEx.IsOrBecomesTrue( - async () => { - result = await Fixture.Projections.GetStateAsync(name, userCredentials: TestCredentials.Root); - return result.Count > 0; - } - ); - - Assert.NotNull(result); - Assert.Equal(1, result!.Count); - } - - [Fact] - public async Task get_status() { - var name = Names.First(); - var result = await Fixture.Projections.GetStatusAsync(name, userCredentials: TestCredentials.Root); - - Assert.NotNull(result); - Assert.Equal(name, result.Name); - } - - [Fact] - public async Task restart_subsystem_does_not_throw() => - await Fixture.Projections.RestartSubsystemAsync(userCredentials: TestCredentials.Root); - - [Fact] - public async Task restart_subsystem_throws_when_given_no_credentials() => - await Assert.ThrowsAsync(() => Fixture.Projections.RestartSubsystemAsync(userCredentials: TestCredentials.TestUser1)); - - [Theory] - [InlineData(true)] - [InlineData(false)] - [InlineData(null)] - public async Task update_projection(bool? emitEnabled) { - var name = Fixture.GetProjectionName(); - await Fixture.Projections.CreateContinuousAsync( - name, - "fromAll().when({$init: function (state, ev) {return {};}});", - userCredentials: TestCredentials.Root - ); - - await Fixture.Projections.UpdateAsync( - name, - "fromAll().when({$init: function (s, e) {return {};}});", - emitEnabled, - userCredentials: TestCredentials.Root - ); - } - static readonly string[] Names = ["$streams", "$stream_by_category", "$by_category", "$by_event_type", "$by_correlation_id"]; - record Result { - public int Count { get; set; } - } - public class CustomFixture : KurrentTemporaryFixture { public CustomFixture() : base(x => x.RunProjections()) { } } diff --git a/test/Kurrent.Client.Tests/Projections/RestartSubsystemTests.cs b/test/Kurrent.Client.Tests/Projections/RestartSubsystemTests.cs new file mode 100644 index 000000000..bd5584a50 --- /dev/null +++ b/test/Kurrent.Client.Tests/Projections/RestartSubsystemTests.cs @@ -0,0 +1,19 @@ +using EventStore.Client; +using Kurrent.Client.Tests.TestNode; + +namespace Kurrent.Client.Tests.Projections; + +public class RestartSubsystemTests(ITestOutputHelper output, RestartSubsystemTests.CustomFixture fixture) + : KurrentTemporaryTests(output, fixture) { + [Fact] + public async Task restart_subsystem_does_not_throw() => + await Fixture.Projections.RestartSubsystemAsync(userCredentials: TestCredentials.Root); + + [Fact] + public async Task restart_subsystem_throws_when_given_no_credentials() => + await Assert.ThrowsAsync(() => Fixture.Projections.RestartSubsystemAsync(userCredentials: TestCredentials.TestUser1)); + + public class CustomFixture : KurrentTemporaryFixture { + public CustomFixture() : base(x => x.RunProjections()) { } + } +} diff --git a/test/Kurrent.Client.Tests/Projections/UpdateProjectionTests.cs b/test/Kurrent.Client.Tests/Projections/UpdateProjectionTests.cs new file mode 100644 index 000000000..a64eb6319 --- /dev/null +++ b/test/Kurrent.Client.Tests/Projections/UpdateProjectionTests.cs @@ -0,0 +1,30 @@ +using Kurrent.Client.Tests.TestNode; + +namespace Kurrent.Client.Tests.Projections; + +public class UpdateProjectionTests(ITestOutputHelper output, UpdateProjectionTests.CustomFixture fixture) + : KurrentTemporaryTests(output, fixture) { + [Theory] + [InlineData(true)] + [InlineData(false)] + [InlineData(null)] + public async Task update_projection(bool? emitEnabled) { + var name = Fixture.GetProjectionName(); + await Fixture.Projections.CreateContinuousAsync( + name, + "fromAll().when({$init: function (state, ev) {return {};}});", + userCredentials: TestCredentials.Root + ); + + await Fixture.Projections.UpdateAsync( + name, + "fromAll().when({$init: function (s, e) {return {};}});", + emitEnabled, + userCredentials: TestCredentials.Root + ); + } + + public class CustomFixture : KurrentTemporaryFixture { + public CustomFixture() : base(x => x.RunProjections()) { } + } +}