Esempio n. 1
0
        public void WhenCreateAdapter_ShouldCreateProperly()
        {
            // Arrange
            byte   expectedData        = 200;
            string adapterExpectedData = expectedData.ToString(CultureInfo.InvariantCulture);
            bool   postActionExecuted  = false;
            bool   stepActionExecuted  = false;
            bool   undoActionExecuted  = false;
            Mock <ITransactionStep <int, byte> > step = new Mock <ITransactionStep <int, byte> >();

            step.SetupGet(x => x.Id)
            .Returns(123);
            step.SetupGet(x => x.Settings)
            .Returns((StepSettings)int.MaxValue);
            step.SetupGet(x => x.PostAction)
            .Returns((byte data, IPostTransactionSessionInfo <int> sessionInfo) =>
            {
                postActionExecuted = true;
                data.Should().Be(expectedData);
            });
            step.SetupGet(x => x.StepAction)
            .Returns((byte data, IStepTransactionSessionInfo <int> sessionInfo) =>
            {
                stepActionExecuted = true;
                data.Should().Be(expectedData);
                sessionInfo.CurrentStepId.Should().Be(step.Object.Id);
            });
            step.SetupGet(x => x.UndoAction)
            .Returns((byte data, IUndoTransactionSessionInfo <int> sessionInfo) =>
            {
                undoActionExecuted = true;
                data.Should().Be(expectedData);
                sessionInfo.CurrentStepId.Should().Be(step.Object.Id);
            });
            step.SetupGet(x => x.PostActionExecutor)
            .Returns(new Mock <IExecutor>().Object);
            step.SetupGet(x => x.StepActionExecutor)
            .Returns(new Mock <IExecutor>().Object);
            step.SetupGet(x => x.UndoActionExecutor)
            .Returns(new Mock <IExecutor>().Object);
            Mock <IStepTransactionSessionInfo <string> > stepInfo = new Mock <IStepTransactionSessionInfo <string> >();

            stepInfo.SetupGet(x => x.CurrentStepId)
            .Returns(step.Object.Id.ToString(CultureInfo.InvariantCulture));
            stepInfo.SetupGet(x => x.Cancelled)
            .Returns(true);
            stepInfo.SetupGet(x => x.Recovered)
            .Returns(true);
            stepInfo.SetupGet(x => x.SessionId)
            .Returns(Guid.NewGuid());
            stepInfo.SetupGet(x => x.StartTimestamp)
            .Returns(DateTime.Now);
            Mock <IUndoTransactionSessionInfo <string> > undoInfo = stepInfo.As <IUndoTransactionSessionInfo <string> >();
            Mock <IPostTransactionSessionInfo <string> > postInfo = undoInfo.As <IPostTransactionSessionInfo <string> >();
            ITransactionStep <string, string>            adapter  = step.Object.Adapter <string, string, int, byte>(id => id.ToString(), idString => int.Parse(idString), data => byte.Parse(data));

            // Act
            adapter.PostAction(adapterExpectedData, postInfo.Object);

            // Assert
            postActionExecuted.Should().BeTrue();

            // Act
            adapter.StepAction(adapterExpectedData, stepInfo.Object);

            // Assert
            stepActionExecuted.Should().BeTrue();

            // Act
            adapter.UndoAction(adapterExpectedData, undoInfo.Object);

            // Assert
            undoActionExecuted.Should().BeTrue();

            // Assert
            int.Parse(adapter.Id).Should().Be(step.Object.Id);
            adapter.Settings.Should().Be(step.Object.Settings);
            adapter.PostActionExecutor.Should().BeSameAs(step.Object.PostActionExecutor);
            adapter.StepActionExecutor.Should().BeSameAs(step.Object.StepActionExecutor);
            adapter.UndoActionExecutor.Should().BeSameAs(step.Object.UndoActionExecutor);
        }
        public static async Task ProcessStep <TStepId, TData>(this ITransactionSession <TStepId, TData> session)
#endif
        {
            ITransactionStep <TStepId, TData> currentStep = session.StepEnumerator.CurrentStep;
            Stopwatch watch = new Stopwatch();

            try
            {
                watch.Start();
#if NET35 || NOASYNC
                currentStep.StepAction(session.StepEnumerator.Data, session);
#else
                if (currentStep.StepAction != null)
                {
                    currentStep.StepAction(session.StepEnumerator.Data, session);
                }
                else
                {
                    await currentStep.AsyncStepAction(session.StepEnumerator.Data, session);
                }
#endif
                watch.Stop();

                if (session.ShouldLogStepExecution())
                {
                    session.TransactionContext
                    .Logger
                    .LogExecutionTime(
                        watch.Elapsed,
                        "Transaction '{0}': execution time for step '{1}' with id '{2}'.",
                        session.TransactionContext.Info.Name,
                        session.StepEnumerator.CurrentStepIndex,
                        currentStep.Id);
                }

                if (session.Cancelled)
                {
                    session.TransactionContext
                    .Logger
                    .InfoFormat("Transaction '{0}' cancelled.", session.TransactionContext.Info.Name);
#if NET35 || NOASYNC
                    RunUndoOperation.RunUndo(new RunUndoContext <TStepId, TData>()
#else
                    await RunUndoOperation.RunUndo(new RunUndoContext <TStepId, TData>()
#endif
                    {
                        Session = session,
                        Result  = ResultType.Cancelled
                    });
                }
            }
            catch (Exception e)
            {
                watch.Stop();
                string info = string.Format("Transaction '{0}': an error occurred during processing step '{1}' with id '{2}', execution time '{3}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, currentStep.Id, watch.Elapsed);
                session.TransactionContext.Logger.ErrorFormat(e, info);
#if NET35 || NOASYNC
                RunUndoOperation.RunUndo(new RunUndoContext <TStepId, TData>()
#else
                await RunUndoOperation.RunUndo(new RunUndoContext <TStepId, TData>()
#endif
                {
                    Session = session,
                    CaughtException = e,
                    Result = ResultType.Failed
                });

#if NET35 || NOASYNC
                SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>()
#else
                await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>()
#endif
                {
                    Session        = session,
                    RunPostActions = false,
                    Result         = ResultType.Failed
                }
                                                                 .AddError(e));
            }
        }