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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using EventStore.Projections.Core.Services;
using EventStore.Projections.Core.Services.Processing;
using EventStore.Projections.Core.Tests.Services.projections_manager;
using NUnit.Framework;

namespace EventStore.Projections.Core.Tests.Integration;

Expand Down Expand Up @@ -34,6 +35,10 @@ protected override void Given()
_trackEmittedStreams = false;
_emitEnabled = false;
_startSystemProjections = GivenStartSystemProjections();
if (!string.IsNullOrEmpty(_projectionSource))
{
Assert.Ignore("Transient query projections are not supported.");
}
}

protected override Tuple<SynchronousScheduler, IPublisher, SynchronousScheduler, Guid>[] GivenProcessingQueues()
Expand Down Expand Up @@ -66,6 +71,8 @@ protected virtual bool GivenStartSystemProjections()

protected Message CreateQueryMessage(string name, string source)
{
Assert.Ignore("Transient query projections are not supported.");

return new ProjectionManagementMessage.Command.Post(
_bus, ProjectionMode.Transient, name,
ProjectionManagementMessage.RunAs.System, "JS", source, enabled: true, checkpointsEnabled: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using EventStore.Projections.Core.Services.Processing;

using EventStore.Projections.Core.Tests.Services.projections_manager;
using NUnit.Framework;

namespace EventStore.Projections.Core.Tests.Services.Jint.Scenarios;

Expand Down Expand Up @@ -36,6 +37,10 @@ protected override void Given()
_trackEmittedStreams = false;
_emitEnabled = false;
_startSystemProjections = GivenStartSystemProjections();
if (!string.IsNullOrEmpty(_projectionSource))
{
Assert.Ignore("Transient query projections are not supported.");
}
}

protected override Tuple<SynchronousScheduler, IPublisher, SynchronousScheduler, Guid>[] GivenProcessingQueues()
Expand Down Expand Up @@ -68,6 +73,8 @@ protected virtual bool GivenStartSystemProjections()

protected Message CreateQueryMessage(string name, string source)
{
Assert.Ignore("Transient query projections are not supported.");

return new ProjectionManagementMessage.Command.Post(
_bus, ProjectionMode.Transient, name,
ProjectionManagementMessage.RunAs.System, "JS", source, enabled: true, checkpointsEnabled: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class ProjectionManagementParityTests<TLogFormat, TStreamId> : Specificat
private GetConfigResp _updatedConfig;
private ReadEventsResp _feedPage;
private StatisticsResp.Types.Details[] _allNonTransientStatistics;
private RpcException _transientCreateFailure;

public override async Task Given()
{
Expand Down Expand Up @@ -70,18 +71,6 @@ await _client.CreateAsync(new CreateReq
}
}, GetCallOptions());

await _client.CreateAsync(new CreateReq
{
Options = new CreateReq.Types.Options
{
Transient = new CreateReq.Types.Options.Types.Transient
{
Name = TransientProjectionName
},
Query = $"fromStream(\"{DebugStream}\").when({{$any:function(s,e){{return s;}}}});"
}
}, GetCallOptions());

await PostEvent(DebugStream, "type1", "{\"value\":1}");
await PostEvent(DebugStream, "type2", "{\"value\":2}");
}
Expand Down Expand Up @@ -153,13 +142,17 @@ await _client.UpdateConfigAsync(new UpdateConfigReq
}
}, GetCallOptions());

await _client.AbortAsync(new AbortReq
_transientCreateFailure = Assert.ThrowsAsync<RpcException>(() => _client.CreateAsync(new CreateReq
{
Options = new AbortReq.Types.Options
Options = new CreateReq.Types.Options
{
Name = TransientProjectionName
Transient = new CreateReq.Types.Options.Types.Transient
{
Name = TransientProjectionName
},
Query = $"fromStream(\"{DebugStream}\").when({{$any:function(s,e){{return s;}}}});"
}
}, GetCallOptions());
}, GetCallOptions()).ResponseAsync);

_allNonTransientStatistics = await ReadStatisticsAsync(new StatisticsReq
{
Expand Down Expand Up @@ -212,11 +205,17 @@ public void read_events_returns_feed_page_details()
}

[Test]
public void all_non_transient_statistics_excludes_transient_projections()
public void create_rejects_transient_projections()
{
Assert.That(_transientCreateFailure.StatusCode, Is.EqualTo(StatusCode.FailedPrecondition));
Assert.That(_transientCreateFailure.Status.Detail, Does.Contain("Transient projections are not supported"));
}

[Test]
public void all_non_transient_statistics_returns_registered_non_transient_projections()
{
Assert.That(_allNonTransientStatistics.Any(x => x.Name == ProjectionName), Is.True);
Assert.That(_allNonTransientStatistics.Any(x => x.Name == DisabledOneTimeProjectionName), Is.True);
Assert.That(_allNonTransientStatistics.Any(x => x.Name == TransientProjectionName), Is.False);
}

[OneTimeTearDown]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public abstract class Base<TLogFormat, TStreamId> : TestFixtureWithProjectionCor
protected override void Given()
{
base.Given();
Assert.Ignore("Transient query projections are not supported.");

_projectionName = "test-projection";
_projectionSource = @"";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,30 +46,24 @@ protected override IEnumerable<WhenStep> When()
checkpointsEnabled: true, emitEnabled: true, trackEmittedStreams: true, enableRunAs: true);
}

[Test, Ignore("ignored")]
public void anonymous_cannot_retrieve_projection_query()
[Test]
public void the_operation_fails()
{
GetInputQueue()
.Publish(
new ProjectionManagementMessage.Command.GetQuery(
Envelope, _projectionName, ProjectionManagementMessage.RunAs.Anonymous));
_queue.Process();
var failure = HandledMessages.OfType<ProjectionManagementMessage.OperationFailed>().Single();

Assert.IsTrue(HandledMessages.OfType<ProjectionManagementMessage.NotAuthorized>().Any());
StringAssert.Contains("Transient projections are not supported", failure.Reason);
}

[Test]
public void projection_owner_can_retrieve_projection_query()
public void the_projection_is_not_registered()
{
GetInputQueue()
.Publish(
new ProjectionManagementMessage.Command.GetQuery(
Envelope, _projectionName, new ProjectionManagementMessage.RunAs(_testUserPrincipal)));
_queue.Process();

var query = HandledMessages.OfType<ProjectionManagementMessage.ProjectionQuery>().FirstOrDefault();
Assert.NotNull(query);
Assert.AreEqual(_projectionBody, query.Query);
Assert.IsTrue(HandledMessages.OfType<ProjectionManagementMessage.NotFound>().Any());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using EventStore.Core.Tests;
using EventStore.Projections.Core.Messages;
using EventStore.Projections.Core.Services;
using NUnit.Framework;

namespace EventStore.Projections.Core.Tests.Services.projections_manager;

[TestFixture(typeof(LogFormat.V2), typeof(string))]
public class when_posting_a_transient_projection<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
{
private const string ProjectionName = "test-projection";
private const string ProjectionBody = "fromAll().when({$any:function(s,e){return s;}});";

protected override void Given()
{
AllWritesSucceed();
NoOtherStreams();
}

protected override IEnumerable<WhenStep> When()
{
yield return new ProjectionSubsystemMessage.StartComponents(Guid.NewGuid());
yield return new ProjectionManagementMessage.Command.Post(
GetInputQueue(),
ProjectionMode.Transient,
ProjectionName,
ProjectionManagementMessage.RunAs.System,
"JS",
ProjectionBody,
enabled: true,
checkpointsEnabled: false,
emitEnabled: false,
trackEmittedStreams: false);
}

[Test, Category("v8")]
public void the_operation_fails()
{
var failure = HandledMessages.OfType<ProjectionManagementMessage.OperationFailed>().Single();

StringAssert.Contains("Transient projections are not supported", failure.Reason);
}

[Test, Category("v8")]
public void the_projection_is_not_registered()
{
GetInputQueue().Publish(new ProjectionManagementMessage.Command.GetQuery(
Envelope,
ProjectionName,
ProjectionManagementMessage.RunAs.System));
_queue.Process();

Assert.IsTrue(HandledMessages.OfType<ProjectionManagementMessage.NotFound>().Any());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
namespace EventStore.Projections.Core.Tests.Services.projections_manager;

[TestFixture(typeof(LogFormat.V2), typeof(string))]
public class when_posting_an_onetime_projection<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
[Ignore("Transient query projections are not supported.")]
public class when_posting_a_transient_query_projection<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
{
protected override void Given()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
namespace EventStore.Projections.Core.Tests.Services.projections_manager;

[TestFixture(typeof(LogFormat.V2), typeof(string))]
public class when_the_onetime_projection_has_been_posted<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
[Ignore("Transient query projections are not supported.")]
public class when_the_transient_query_projection_has_been_posted<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
{
private string _projectionName;
private string _projectionQuery;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
namespace EventStore.Projections.Core.Tests.Services.projections_manager;

[TestFixture(typeof(LogFormat.V2), typeof(string))]
public class when_updating_an_onetime_projection_query_text<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
[Ignore("Transient query projections are not supported.")]
public class when_updating_a_transient_query_projection_text<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
{
private string _projectionName;
private string _newProjectionSource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
namespace EventStore.Projections.Core.Tests.Services.projections_manager;

[TestFixture(typeof(LogFormat.V2), typeof(string))]
public class when_updating_an_onetime_system_projection_query_text<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
[Ignore("Transient query projections are not supported.")]
public class when_updating_a_transient_system_query_projection_text<TLogFormat, TStreamId> : TestFixtureWithProjectionCoreAndManagementServices<TLogFormat, TStreamId>
{
private string _projectionName;
private string _newProjectionSource;
Expand All @@ -30,7 +31,6 @@ protected override IEnumerable<WhenStep> When()
_bus, ProjectionMode.Transient, _projectionName,
ProjectionManagementMessage.RunAs.Anonymous, "native:EventStore.Projections.Core.Standard.ByCorrelationId", "{\"correlationIdProperty\":\"$myCorrelationId\"}",
enabled: true, checkpointsEnabled: false, emitEnabled: false, trackEmittedStreams: true));
// when
_newProjectionSource = "{\"correlationIdProperty\":\"$updateCorrelationId\"}";
yield return
(new ProjectionManagementMessage.Command.UpdateQuery(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public Post(
_definitionMetadata = definitionMetadata ?? Empty.ByteArray;
}

// shortcut for posting ad-hoc JS queries
// Kept so legacy ad-hoc JS callers fail through the transient projection boundary.
public Post(IEnvelope envelope, RunAs runAs, string query, bool enabled)
: base(envelope, runAs)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,8 @@ public void Handle(ProjectionManagementMessage.Command.Post message)

if (message.Mode == ProjectionMode.Transient)
{
var transientProjection = new PendingProjection(ProjectionQueryId, message);
if (!ValidateProjections(new[] { transientProjection }, message))
{
return;
}

PostNewTransientProjection(transientProjection, message.Envelope);
message.Envelope.ReplyWith(new ProjectionManagementMessage.OperationFailed(
"Transient projections are not supported."));
}
else
{
Expand Down Expand Up @@ -1228,14 +1223,6 @@ private ProjectionManagementMessage.Command.PostBatch.ProjectionPost CreateSyste
enableRunAs: true);
}

private void PostNewTransientProjection(PendingProjection projection, IEnvelope replyEnvelope)
{
var initializer = projection.CreateInitializer(replyEnvelope);
ReadProjectionPossibleStream(projection.Name,
m => ReadProjectionPossibleStreamCompleted
(m, initializer, replyEnvelope));
}

private void PostNewProjections
(IDictionary<string, PendingProjection> newProjections, long expectedVersion, IEnvelope replyEnvelope)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ protected virtual ICoreProjectionCheckpointManager CreateCheckpointManager(
{
var emitAny = _projectionConfig.EmitEventEnabled;

//NOTE: not emitting one-time/transient projections are always handled by default checkpoint manager
// as they don't depend on stable event order
// Unordered reads need the multi-output checkpoint manager only when emitted output must be repeatable.
if (emitAny && !readerStrategy.IsReadingOrderRepeatable)
{
return new MultiStreamMultiOutputCheckpointManager(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public void Handle(ReaderSubscriptionMessage.EventReaderIdle message)

protected override void EofReached()
{
// flush all available events as wqe reached eof (currently onetime projections only)
// EOF means no earlier event can still arrive, so every buffered event can be released.
ProcessAllFor(DateTime.MaxValue);
}

Expand Down
Loading