示例#1
0
        public When_the_subscription_runner_processing_a_stream_event_throws_a_detected_stream_gap_exception()
        {
            var fixture = new Fixture();

            _commandBusMock = new Mock <IConnectedProjectionsCommandBus>();
            var streamMock = new Mock <IConnectedProjectionsStreamStoreSubscription>();

            streamMock
            .SetupGet(stream => stream.StreamIsRunning)
            .Returns(true);

            var contextMock = new Mock <IConnectedProjectionContext <FakeProjectionContext> >();

            contextMock
            .Setup(context => context.GetProjectionPosition(It.IsAny <ConnectedProjectionIdentifier>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync((long?)null);

            var missingMessagesPositions = fixture.CreateMany <long>(2, 10).ToList();

            _registeredProjections = new List <IConnectedProjection>
            {
                new FakeProjection(
                    $"{MissingMessageProjectionIdentifier}-1",
                    ThrowMissingMessageException(missingMessagesPositions),
                    contextMock.Object),
                new FakeProjection(
                    "do-nothing",
                    (messages, strategy, name, ct) => Task.CompletedTask,
                    contextMock.Object),
                new FakeProjection(
                    $"{MissingMessageProjectionIdentifier}-2",
                    ThrowMissingMessageException(missingMessagesPositions),
                    contextMock.Object)
            };

            var registeredProjectionsMock = new Mock <IRegisteredProjections>();

            registeredProjectionsMock
            .Setup(projections => projections.GetProjection(It.IsAny <ConnectedProjectionIdentifier>()))
            .Returns((ConnectedProjectionIdentifier projectionId) => _registeredProjections.FirstOrDefault(projection => projection.Id.Equals(projectionId)));

            var loggerFactory = new FakeLoggerFactory();

            _loggerMock = loggerFactory.ResolveLoggerMock <ConnectedProjectionsSubscriptionRunner>();

            _gapStrategySettings = fixture.Create <StreamGapStrategyConfigurationSettings>();
            var gapStrategyMock = new Mock <IStreamGapStrategy>();

            gapStrategyMock
            .SetupGet(strategy => strategy.Settings)
            .Returns(_gapStrategySettings);

            _sut = new ConnectedProjectionsSubscriptionRunner(
                registeredProjectionsMock.Object,
                streamMock.Object,
                _commandBusMock.Object,
                gapStrategyMock.Object,
                loggerFactory);

            foreach (var projection in _registeredProjections)
            {
                _sut.HandleSubscriptionCommand(new Subscribe(projection.Id)).GetAwaiter();
            }

            VerifySetup();
            _sut.HandleSubscriptionCommand(new ProcessStreamEvent(fixture.Create <StreamMessage>(), fixture.Create <CancellationToken>())).GetAwaiter();
        }
示例#2
0
        public When_a_projection_catch_up_processes_a_stream_and_throws_a_detected_stream_gap_exception()
        {
            var fixture = new Fixture()
                          .CustomizeConnectedProjectionIdentifiers();

            var contextMock = new Mock <IConnectedProjectionContext <FakeProjectionContext> >();

            contextMock
            .Setup(context => context.GetProjectionPosition(It.IsAny <ConnectedProjectionIdentifier>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync((long?)null);

            var streamMock = new Mock <IReadonlyStreamStore>();

            streamMock
            .Setup(store =>
                   store.ReadAllForwards(
                       It.IsAny <long>(),
                       It.IsAny <int>(),
                       It.IsAny <bool>(),
                       It.IsAny <CancellationToken>()))
            .ReturnsAsync(() =>
            {
                var position = fixture.CreatePositive <long>().WithMaximumValueOf(long.MaxValue - 1000);
                return(new ReadAllPage(
                           position,
                           position.CreateRandomHigherValue(),
                           true,
                           ReadDirection.Forward,
                           (p, token) => throw new NotImplementedException(),
                           fixture.CreateMany <StreamMessage>(2, 10).ToArray()));
            });

            _commandBusMock = new Mock <IConnectedProjectionsCommandBus>();

            _gapStrategySettings = fixture.Create <StreamGapStrategyConfigurationSettings>();
            var gapStrategyMock = new Mock <IStreamGapStrategy>();

            gapStrategyMock
            .SetupGet(strategy => strategy.Settings)
            .Returns(_gapStrategySettings);

            _loggerMock = new FakeLogger();
            _projection = new FakeProjection(
                "catch-up-dummy",
                (messages, strategy, name, ct)
                => throw new ConnectedProjectionMessageHandlingException(
                    new StreamGapDetectedException(fixture.CreateMany <long>(1, 10), name),
                    name,
                    new ActiveProcessedStreamState(0)),
                contextMock.Object);

            var sut = new ConnectedProjectionCatchUp <FakeProjectionContext>(
                _projection,
                ConnectedProjectionSettings.Default,
                streamMock.Object,
                _commandBusMock.Object,
                gapStrategyMock.Object,
                _loggerMock.AsLogger());

            sut.CatchUpAsync(CancellationToken.None).GetAwaiter();
        }
示例#3
0
        public When_handling_a_message_with_position_within_and_creation_outside_stream_end_buffer_using_the_default_catchup_stream_gap_strategy()
        {
            var fixture = new Fixture()
                          .CustomizeConnectedProjectionIdentifiers();

            _projection       = fixture.Create <ConnectedProjectionIdentifier>();
            _missingPositions = fixture.CreateMany <long>(1, 10);

            var settings = new StreamGapStrategyConfigurationSettings
            {
                StreamBufferInSeconds = fixture.CreatePositive <int>(),
                PositionBufferSize    = fixture.CreatePositive <int>()
            };

            var streamHeadPosition = fixture
                                     .CreatePositive <long>()
                                     .WithMinimumValueOf(settings.PositionBufferSize + 100);
            var streamStoreMock = new Mock <IReadonlyStreamStore>();

            streamStoreMock
            .Setup(store => store.ReadHeadPosition(It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(streamHeadPosition));

            var now = fixture
                      .Create <DateTime>()
                      .ToUniversalTime();
            var clockMock = new Mock <IClock>();

            clockMock
            .Setup(clock => clock.GetCurrentInstant())
            .Returns(Instant.FromDateTimeUtc(now));

            var message = (StreamMessage)fixture
                          .Build <ConfigurableStreamMessage>()
                          .WithPosition(streamHeadPosition
                                        .CreateRandomLowerValue()
                                        .WithMinimumValueOf(streamHeadPosition + 1 - settings.PositionBufferSize))
                          .WithCreatedUtc(now.AddSeconds(0 - settings.StreamBufferInSeconds))
                          .Create();

            var stateMock = new Mock <IProcessedStreamState>();

            stateMock
            .Setup(state => state.DetermineGapPositions(message))
            .Returns(_missingPositions);

            var fakeLoggerFactory = new FakeLoggerFactory();

            _loggerMock = fakeLoggerFactory.ResolveLoggerMock <DefaultCatchUpStreamGapStrategy>();

            _processMessageFunctionStatus = "NotExecuted";

            new DefaultCatchUpStreamGapStrategy(fakeLoggerFactory, settings, streamStoreMock.Object, clockMock.Object)
            .HandleMessage(
                message,
                stateMock.Object,
                (_, token) =>
            {
                _processMessageFunctionStatus = "Executed";
                return(Task.CompletedTask);
            },
                _projection,
                fixture.Create <CancellationToken>())
            .GetAwaiter();
        }