public static async Task ProcessUndo <TStepId, TData>(RunUndoContext <TStepId, TData> context) #endif { ITransactionStep <TStepId, TData> currentStep = context.Session.StepEnumerator.CurrentStep; ITransactionSession <TStepId, TData> session = context.Session; Stopwatch watch = new Stopwatch(); try { watch.Start(); #if NET35 || NOASYNC currentStep.UndoAction(session.StepEnumerator.Data, session); #else if (currentStep.UndoAction != null) { currentStep.UndoAction(session.StepEnumerator.Data, session); } else { await currentStep.AsyncUndoAction(session.StepEnumerator.Data, session); } #endif watch.Stop(); #if NET35 || NOASYNC context.Session.TransactionContext.SessionStorage.StepReceding(session); #else await context.Session.TransactionContext.SessionStorage.StepReceding(session); #endif if (session.ShouldLogStepExecution()) { session.TransactionContext .Logger .LogExecutionTime( watch.Elapsed, "Transaction '{0}': execution time for undo step action for step '{1}' with id '{2}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, currentStep.Id); } } catch (Exception e) { watch.Stop(); string info = string.Format( "Transaction '{0}': an error occurred during processing undo step action for 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 SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #else await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #endif { Session = context.Session, RunPostActions = false, Result = ResultType.Failed } .AddError(context.CaughtException) .AddError(e)); } }
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); }