public void WhenRunTransactionWithStepExecutorsWithSameExecutorForAllActions_ShouldRunAllStepsProperly()
        {
            // Arrange
            object        transactionData                = new object();
            List <string> runStepActions                 = new List <string>();
            List <string> runUndoActions                 = new List <string>();
            List <string> runPostActions                 = new List <string>();
            List <int>    stepActionThreadId             = new List <int>();
            List <int>    postActionThreadId             = new List <int>();
            int           transactionCallbackThreadId    = 0;
            Dictionary <int, TestExecutor> stepExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, null },
                { 1, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 2, null },
                { 3, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 4, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 5, null },
                { 6, null }
            };
            Dictionary <int, TestExecutor> postExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, null },
                { 1, null },
                { 2, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 3, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 4, null },
                { 5, null },
                { 6, null }
            };
            int          transactionRunThreadId  = Thread.CurrentThread.ManagedThreadId;
            int          step1StepActionThreadId = stepExecutors[1].ThreadId;
            int          step2PostActionThreadId = postExecutors[2].ThreadId;
            int          step3StepActionThreadId = stepExecutors[3].ThreadId;
            int          step3PostActionThreadId = postExecutors[3].ThreadId;
            int          step4StepActionThreadId = stepExecutors[4].ThreadId;
            TestExecutor callbackExecutor        = new TestExecutor()
            {
                ShouldRun = true
            };
            ITransaction <string, object> target = new TransactionFactory().Create <string, object>(options =>
            {
                options.TransactionInfo.Name = "test transaction";
            });

            for (int i = 0; i < 7; ++i)
            {
                string index = i.ToString();
                TransactionStep <string, object> step = new TransactionStep <string, object>()
                {
                    Id = index,
                    StepActionExecutor = stepExecutors[i] == null
                                           ? null
                                           : stepExecutors[i],
                    PostActionExecutor = postExecutors[i] == null
                                           ? null
                                           : postExecutors[i],
                    Settings = i == 1
                                ? StepSettings.SameExecutorForAllActions
                                : StepSettings.None
                };

                step.StepAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    info.CurrentStepId.Should().Be(index);
                    runStepActions.Add(index);
                    stepActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                };

                step.UndoAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    info.CurrentStepId.Should().Be(index);
                    runUndoActions.Add(index);
                };

                step.PostAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    runPostActions.Add(index);
                    postActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                    info.CurrentStepId.Should().Be(index);
                };

                target.Add(step);
            }
            ITransactionResult <object> result = null;

            /*
             * 0:
             * 1: executor for other thread (step action), SameExecutorForAllActions
             * 2: executor for other thread (post action)
             * 3: executor for other thread (step action), executor for other thread (post action)
             * 4: executor for other thread (step action)
             * 5:
             * 6:
             */

            // Act
            using (ManualResetEvent transactionEndResetEvent = new ManualResetEvent(false))
            {
                target.Run(settings =>
                {
                    settings.Data = transactionData;
                    settings.Mode = RunMode.Run;
                    settings.TransactionResultCallback = callbackResult =>
                    {
                        transactionCallbackThreadId = Thread.CurrentThread.ManagedThreadId;
                        result = callbackResult;
                        transactionEndResetEvent.Set();
                    };
                    settings.TransactionResultCallbackExecutor = callbackExecutor;
                });
                transactionEndResetEvent.WaitOne();
            }

            // Assert
            callbackExecutor.Dispose();

            foreach (TestExecutor executor in stepExecutors.Values.Concat(postExecutors.Values).Where(x => x != null))
            {
                executor.Dispose();
            }

            result.Data.Should().BeSameAs(transactionData);
            result.Errors.ShouldAllBeEquivalentTo(new Exception[0]);
            result.Recovered.Should().BeFalse();
            result.Result.Should().Be(ResultType.Success);
            TestExecutor sharedExecutor = stepExecutors[1];

            sharedExecutor.Mock.VerifyGet(x => x.ShouldRun, Times.Exactly(2));
            sharedExecutor.Mock.Verify(x => x.Run(It.IsNotNull <Action>()), Times.Exactly(2));
            callbackExecutor.Verify(Times.Once, Times.Once);

            foreach (TestExecutor executor in stepExecutors.Values.Concat(postExecutors.Values).Where(x => x != null && x != sharedExecutor))
            {
                executor.Verify(Times.Once, Times.Once);
            }

            runStepActions.ShouldAllBeEquivalentTo(new string[] { "0", "1", "2", "3", "4", "5", "6" });
            runUndoActions.ShouldAllBeEquivalentTo(new string[0]);
            runPostActions.ShouldAllBeEquivalentTo(new string[] { "0", "1", "2", "3", "4", "5", "6" });
            stepActionThreadId.ShouldAllBeEquivalentTo(new int[]
            {
                /*step 0*/ transactionRunThreadId,
                /*step 1*/ step1StepActionThreadId,
                /*step 2*/ step1StepActionThreadId,
                /*step 3*/ step3StepActionThreadId,
                /*step 4*/ step4StepActionThreadId,
                /*step 5*/ step4StepActionThreadId,
                /*step 6*/ step4StepActionThreadId
            });
            postActionThreadId.ShouldAllBeEquivalentTo(new int[]
            {
                /*step 0*/ step4StepActionThreadId,
                /*step 1*/ step1StepActionThreadId,
                /*step 2*/ step2PostActionThreadId,
                /*step 3*/ step3PostActionThreadId,
                /*step 4*/ step3PostActionThreadId,
                /*step 5*/ step3PostActionThreadId,
                /*step 6*/ step3PostActionThreadId
            });
            transactionCallbackThreadId.Should().Be(callbackExecutor.ThreadId);
        }
Пример #2
0
        public void WhenRecoverTransactionFromFirstStepWithStepExecutors_ShouldRunAllStepsProperly()
        {
            // Arrange
            object        transactionData                = new object();
            List <string> runStepActions                 = new List <string>();
            List <string> runUndoActions                 = new List <string>();
            List <string> runPostActions                 = new List <string>();
            List <int>    stepActionThreadId             = new List <int>();
            List <int>    undoActionThreadId             = new List <int>();
            List <int>    postActionThreadId             = new List <int>();
            int           transactionCallbackThreadId    = 0;
            Dictionary <int, TestExecutor> stepExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, null },
                { 1, null },
                { 2, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 3, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 4, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 5, null },
                { 6, null }
            };
            Dictionary <int, TestExecutor> undoExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 1, null },
                { 2, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 3, null },
                { 4, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 5, null },
                { 6, null }
            };
            Dictionary <int, TestExecutor> postExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, null },
                { 1, null },
                { 2, null },
                { 3, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 4, null },
                { 5, null },
                { 6, null }
            };
            TestExecutor callBackExecutor = new TestExecutor()
            {
                ShouldRun = true
            };
            Mock <ITransactionStorage <object> > storageMock   = new Mock <ITransactionStorage <object> >();
            Mock <ITransactionData <object> >    recoveredData = new Mock <ITransactionData <object> >();

            recoveredData.SetupGet(x => x.CurrentStepIndex)
            .Returns(0);
            recoveredData.SetupGet(x => x.Data)
            .Returns(transactionData);
            recoveredData.SetupGet(x => x.SessionId)
            .Returns(Guid.NewGuid());
            recoveredData.SetupGet(x => x.StartTimestamp)
            .Returns(DateTime.Now);
            storageMock.Setup(x => x.RecoverTransaction())
            .Returns(recoveredData.Object);
            ITransaction <string, object> target = new TransactionFactory().Create <string, object>(options =>
            {
                options.TransactionInfo.Name      = "test transaction";
                options.TransactionStorageCreator = context => storageMock.Object;
            });

            for (int i = 0; i < 7; ++i)
            {
                string index = i.ToString();
                TransactionStep <string, object> step = new TransactionStep <string, object>()
                {
                    Id = index,
                    StepActionExecutor = stepExecutors[i],
                    UndoActionExecutor = undoExecutors[i],
                    PostActionExecutor = postExecutors[i],
                    Settings           = i == 0 ? StepSettings.UndoOnRecover : StepSettings.None
                };

                step.StepAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    info.CurrentStepId.Should().Be(index);
                    runStepActions.Add(index);
                    stepActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                };

                step.UndoAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    info.CurrentStepId.Should().Be(index);
                    runUndoActions.Add(index);
                    undoActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                };

                step.PostAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    runPostActions.Add(index);
                    postActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                    info.CurrentStepId.Should().Be(index);
                };

                target.Add(step);
            }
            ITransactionResult <object> result = null;

            /*
             * 0: recovered step, undo on recover, executor for other thread (undo action)
             * 1:
             * 2: executor for other thread (step action), executor for other thread (undo action)
             * 3: executor for other thread (step action), executor for other thread (post action)
             * 4: executor for other thread (step action), executor for other thread (undo action)
             * 5:
             * 6:
             */

            // Act
            using (ManualResetEvent transactionEndResetEvent = new ManualResetEvent(false))
            {
                target.Run(settings =>
                {
                    settings.Data = transactionData;
                    settings.Mode = RunMode.RecoverAndContinue;
                    settings.TransactionResultCallback = callbackResult =>
                    {
                        transactionCallbackThreadId = Thread.CurrentThread.ManagedThreadId;
                        result = callbackResult;
                        transactionEndResetEvent.Set();
                    };
                    settings.TransactionResultCallbackExecutor = callBackExecutor;
                });
                transactionEndResetEvent.WaitOne();
            }

            // Assert
            callBackExecutor.Dispose();

            foreach (TestExecutor executor in stepExecutors.Values.Concat(postExecutors.Values).Where(x => x != null))
            {
                executor.Dispose();
            }

            result.Data.Should().BeSameAs(transactionData);
            result.Errors.ShouldAllBeEquivalentTo(new Exception[0]);
            result.Recovered.Should().BeTrue();
            result.Result.Should().Be(ResultType.Success);
            callBackExecutor.Verify(Times.Once, Times.Once);

            foreach (TestExecutor executor in stepExecutors.Values.Concat(postExecutors.Values).Where(x => x != null))
            {
                executor.Verify(Times.Once, Times.Once);
            }

            runStepActions.ShouldAllBeEquivalentTo(new string[] { "0", "1", "2", "3", "4", "5", "6" });
            runUndoActions.ShouldAllBeEquivalentTo(new string[] { "0" });
            runPostActions.ShouldAllBeEquivalentTo(new string[] { "0", "1", "2", "3", "4", "5", "6" });
            stepActionThreadId.ShouldAllBeEquivalentTo(new int[]
            {
                /*step 0*/ undoExecutors[0].ThreadId,
                /*step 1*/ undoExecutors[0].ThreadId,
                /*step 2*/ stepExecutors[2].ThreadId,
                /*step 3*/ stepExecutors[3].ThreadId,
                /*step 4*/ stepExecutors[4].ThreadId,
                /*step 5*/ stepExecutors[4].ThreadId,
                /*step 6*/ stepExecutors[4].ThreadId
            });
            undoActionThreadId.ShouldAllBeEquivalentTo(new int[]
            {
                /*step 0*/ undoExecutors[0].ThreadId,
            });
            postActionThreadId.ShouldAllBeEquivalentTo(new int[]
            {
                /*step 0*/ stepExecutors[4].ThreadId,
                /*step 1*/ stepExecutors[4].ThreadId,
                /*step 2*/ stepExecutors[4].ThreadId,
                /*step 3*/ postExecutors[3].ThreadId,
                /*step 4*/ postExecutors[3].ThreadId,
                /*step 5*/ postExecutors[3].ThreadId,
                /*step 6*/ postExecutors[3].ThreadId
            });
            transactionCallbackThreadId.Should().Be(callBackExecutor.ThreadId);
            storageMock.AssertStorageOperations(new AssertStorageOperationsContext <string, object>()
            {
                SessionStartedTimes = Times.Never(),
                TransactionData     = transactionData,
                Transaction         = target,
                ExpectedStepsOrder  = runStepActions,
                ExpectedUndoOrder   = runUndoActions
            });
        }
Пример #3
0
        public void WhenGoForwardWithComparerWithCompareFailureWithStepExecutors_ShouldFailTransaction()
        {
            // Arrange
            object        transactionData                = new object();
            List <string> runStepActions                 = new List <string>();
            List <string> runUndoActions                 = new List <string>();
            List <string> runPostActions                 = new List <string>();
            List <int>    stepActionThreadId             = new List <int>();
            List <int>    postActionThreadId             = new List <int>();
            int           transactionCallbackThreadId    = 0;
            Dictionary <int, TestExecutor> stepExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, null },
                { 1, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 2, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 3, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 4, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 5, null },
                { 6, null }
            };
            Dictionary <int, TestExecutor> postExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, null },
                { 1, null },
                { 2, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 3, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 4, null },
                { 5, null },
                { 6, null }
            };
            int          transactionRunThreadId = Thread.CurrentThread.ManagedThreadId;
            TestExecutor callBackExecutor       = new TestExecutor()
            {
                ShouldRun = true
            };
            ITransaction <string, object> target = new TransactionFactory().Create <string, object>(options =>
            {
                options.TransactionInfo.Name = "test transaction";
            });

            for (int i = 0; i < 7; ++i)
            {
                string index = "B" + i.ToString();
                TransactionStep <string, object> step = new TransactionStep <string, object>()
                {
                    Id = index,
                    StepActionExecutor = stepExecutors[i] == null
                                           ? null
                                           : stepExecutors[i],
                    PostActionExecutor = postExecutors[i] == null
                                           ? null
                                           : postExecutors[i]
                };

                step.StepAction = (data, info) =>
                {
                    if (info.CurrentStepId == "B2")
                    {
                        info.GoForward("b4", StringComparer.Ordinal);
                    }

                    data.Should().BeSameAs(transactionData);
                    info.CurrentStepId.Should().Be(index);
                    runStepActions.Add(index);
                    stepActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                };

                step.UndoAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    info.CurrentStepId.Should().Be(index);
                    runUndoActions.Add(index);
                };

                step.PostAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    runPostActions.Add(index);
                    postActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                    info.CurrentStepId.Should().Be(index);
                };

                target.Add(step);
            }

            /*
             * 0:
             * 1: executor for other thread (step action)
             * 2: executor for other thread (step action), executor for other thread (post action), go forward to step 4
             * 3: executor for other thread (step action), executor for other thread (post action)
             * 4: executor for other thread (step action)
             * 5:
             * 6:
             */

            // Act
            ITransactionResult <object> result = null;

            using (ManualResetEvent transactionEndResetEvent = new ManualResetEvent(false))
            {
                target.Run(settings =>
                {
                    settings.Data = transactionData;
                    settings.Mode = RunMode.Run;
                    settings.TransactionResultCallback = callbackResult =>
                    {
                        transactionCallbackThreadId = Thread.CurrentThread.ManagedThreadId;
                        result = callbackResult;
                        transactionEndResetEvent.Set();
                    };
                    settings.TransactionResultCallbackExecutor = callBackExecutor;
                });
                transactionEndResetEvent.WaitOne();
            }

            // Assert
            callBackExecutor.Dispose();

            foreach (TestExecutor executor in stepExecutors.Values.Concat(postExecutors.Values).Where(x => x != null))
            {
                executor.Dispose();
            }

            result.Data.Should().BeSameAs(transactionData);
            result.Errors.Count().Should().Be(1);
            result.Errors.First().Message.Contains("Could not move forward to a step with id 'b4' as the step does not exist.").Should().BeTrue();
            result.Recovered.Should().BeFalse();
            result.Result.Should().Be(ResultType.Failed);
            runStepActions.ShouldAllBeEquivalentTo(new string[] { "B0", "B1", "B2" });
            runUndoActions.ShouldAllBeEquivalentTo(new string[] { "B2", "B1", "B0" });
            runPostActions.ShouldAllBeEquivalentTo(new string[0]);
            stepActionThreadId.ShouldAllBeEquivalentTo(new int[]
            {
                /*step 0*/ transactionRunThreadId,
                /*step 1*/ stepExecutors[1].ThreadId,
                /*step 2*/ stepExecutors[2].ThreadId
            });
            transactionCallbackThreadId.Should().Be(callBackExecutor.ThreadId);
        }
        public void WhenGoBackWithComparerWithCompareSuccessWithStepExecutors_ShouldMoveToStepProperly()
        {
            // Arrange
            object        transactionData                = new object();
            List <string> runStepActions                 = new List <string>();
            List <string> runUndoActions                 = new List <string>();
            List <string> runPostActions                 = new List <string>();
            List <int>    stepActionThreadId             = new List <int>();
            List <int>    postActionThreadId             = new List <int>();
            int           transactionCallbackThreadId    = 0;
            Dictionary <int, TestExecutor> stepExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, null },
                { 1, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 2, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 3, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 4, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 5, null },
                { 6, null }
            };
            Dictionary <int, TestExecutor> postExecutors = new Dictionary <int, TestExecutor>()
            {
                { 0, null },
                { 1, null },
                { 2, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 3, new TestExecutor()
                  {
                      ShouldRun = true
                  } },
                { 4, null },
                { 5, null },
                { 6, null }
            };
            int          transactionRunThreadId = Thread.CurrentThread.ManagedThreadId;
            TestExecutor callBackExecutor       = new TestExecutor()
            {
                ShouldRun = true
            };
            ITransaction <string, object> target = new TransactionFactory().Create <string, object>(options =>
            {
                options.TransactionInfo.Name = "test transaction";
            });
            int goBackCounter = 0;

            for (int i = 0; i < 7; ++i)
            {
                string index = "B" + i.ToString();
                TransactionStep <string, object> step = new TransactionStep <string, object>()
                {
                    Id = index,
                    StepActionExecutor = stepExecutors[i] == null
                                           ? null
                                           : stepExecutors[i],
                    PostActionExecutor = postExecutors[i] == null
                                           ? null
                                           : postExecutors[i]
                };

                step.StepAction = (data, info) =>
                {
                    if (info.CurrentStepId == "B2" &&
                        goBackCounter++ == 0)
                    {
                        info.GoBack("b0", StringComparer.OrdinalIgnoreCase);
                    }

                    data.Should().BeSameAs(transactionData);
                    info.CurrentStepId.Should().Be(index);
                    runStepActions.Add(index);
                    stepActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                };

                step.UndoAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    info.CurrentStepId.Should().Be(index);
                    runUndoActions.Add(index);
                };

                step.PostAction = (data, info) =>
                {
                    data.Should().BeSameAs(transactionData);
                    runPostActions.Add(index);
                    postActionThreadId.Add(Thread.CurrentThread.ManagedThreadId);
                    info.CurrentStepId.Should().Be(index);
                };

                target.Add(step);
            }

            /*
             * 0:
             * 1: executor for other thread (step action)
             * 2: executor for other thread (step action), executor for other thread (post action), go back to step 0
             * 3: executor for other thread (step action), executor for other thread (post action)
             * 4: executor for other thread (step action)
             * 5:
             * 6:
             */

            // Act
            ITransactionResult <object> result = null;

            using (ManualResetEvent transactionEndResetEvent = new ManualResetEvent(false))
            {
                target.Run(settings =>
                {
                    settings.Data = transactionData;
                    settings.Mode = RunMode.Run;
                    settings.TransactionResultCallback = callbackResult =>
                    {
                        transactionCallbackThreadId = Thread.CurrentThread.ManagedThreadId;
                        result = callbackResult;
                        transactionEndResetEvent.Set();
                    };
                    settings.TransactionResultCallbackExecutor = callBackExecutor;
                });
                transactionEndResetEvent.WaitOne();
            }

            // Assert
            callBackExecutor.Dispose();

            foreach (TestExecutor executor in stepExecutors.Values.Concat(postExecutors.Values).Where(x => x != null))
            {
                executor.Dispose();
            }

            result.Data.Should().BeSameAs(transactionData);
            result.Errors.ShouldAllBeEquivalentTo(new Exception[0]);
            result.Recovered.Should().BeFalse();
            result.Result.Should().Be(ResultType.Success);
            callBackExecutor.Verify(Times.Once, Times.Once);

            foreach (TestExecutor executor in stepExecutors.Values.Concat(postExecutors.Values).Where(x => x != null))
            {
                executor.Verify(Times.AtLeastOnce, Times.AtLeastOnce);
            }

            runStepActions.ShouldAllBeEquivalentTo(new string[] { "B0", "B1", "B2", "B0", "B1", "B2", "B3", "B4", "B5", "B6" });
            runUndoActions.ShouldAllBeEquivalentTo(new string[] { "B2", "B1", "B0" });
            runPostActions.ShouldAllBeEquivalentTo(new string[] { "B0", "B1", "B2", "B3", "B4", "B5", "B6" });
            stepActionThreadId.ShouldAllBeEquivalentTo(new int[]
            {
                /*step 0*/ transactionRunThreadId,
                /*step 1*/ stepExecutors[1].ThreadId,
                /*step 2*/ stepExecutors[2].ThreadId,
                /*step 0*/ stepExecutors[2].ThreadId,
                /*step 1*/ stepExecutors[1].ThreadId,
                /*step 2*/ stepExecutors[2].ThreadId,
                /*step 3*/ stepExecutors[3].ThreadId,
                /*step 4*/ stepExecutors[4].ThreadId,
                /*step 5*/ stepExecutors[4].ThreadId,
                /*step 6*/ stepExecutors[4].ThreadId
            });
            postActionThreadId.ShouldAllBeEquivalentTo(new int[]
            {
                /*step 0*/ stepExecutors[4].ThreadId,
                /*step 1*/ stepExecutors[4].ThreadId,
                /*step 2*/ postExecutors[2].ThreadId,
                /*step 3*/ postExecutors[3].ThreadId,
                /*step 4*/ postExecutors[3].ThreadId,
                /*step 5*/ postExecutors[3].ThreadId,
                /*step 6*/ postExecutors[3].ThreadId
            });
            transactionCallbackThreadId.Should().Be(callBackExecutor.ThreadId);
        }