Exemplo n.º 1
0
        private static void TestCase_VolatileEnlistments(
            int count,
            TransactionStatus expectedOutcome,
            EnlistmentOptions options = EnlistmentOptions.None,
            bool commitTx = true,
            bool votePrepared = true,
            Type expectedExceptionType = null)
        {
            string testCaseDescription = string.Format("TestCase_VolatileEnlistments; count = {0}; expectedOutcome = {1}; options = {2}; votePrepared = {3}, expectedExceptionType = {4}",
                        count,
                        expectedOutcome.ToString(),
                        options.ToString(),
                        votePrepared,
                        expectedExceptionType);

            Trace("**** " + testCaseDescription + " ****");

            AutoResetEvent[] enlistmentDoneEvts = new AutoResetEvent[count];
            MyEnlistment[] vols = new MyEnlistment[count];
            for (int i = 0; i < count; i++)
            {
                enlistmentDoneEvts[i] = new AutoResetEvent(false);
            }

            try
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    for (int i = 0; i < count; i++)
                    {
                        vols[i] = CreateVolatileEnlistment(enlistmentDoneEvts[i], null, options, votePrepared);
                    }
                    if (commitTx)
                    {
                        ts.Complete();
                    }
                }
            }
            catch (Exception ex)
            {
                if (ex.GetType() != expectedExceptionType)
                {
                    TestFailed(testCaseDescription, string.Format("Unexpected exception {0}: {1}", ex.GetType().ToString(), ex.ToString()));
                    return;
                }
            }

            for (int i = 0; i < count; i++)
            {
                if (!enlistmentDoneEvts[i].WaitOne(TimeSpan.FromSeconds(5)))
                {
                    TestFailed(testCaseDescription, "Timeout waiting for enlistment outcomes");
                    return;
                }
            }

            int passCount = 0;
            for (int i = 0; i < count; i++)
            {
                if (((expectedOutcome == TransactionStatus.Committed) && vols[i].CommittedOutcome) ||
                    ((expectedOutcome == TransactionStatus.Aborted) && vols[i].AbortedOutcome) ||
                    ((expectedOutcome == TransactionStatus.InDoubt) && vols[i].InDoubtOutcome)
                    )
                {
                    passCount++;
                }
            }
            if (passCount == count)
            {
                TestPassed();
            }
            else
            {
                TestFailed(testCaseDescription, string.Format("{0} enlistments received an outcome of {1}", passCount, expectedOutcome.ToString()));
            }
        }
Exemplo n.º 2
0
        private static void TestCase_PSPENonMsdtc(bool commit,
            bool promote,
            TransactionStatus spcResponse,
            int p0BeforePSPE = 0,
            int p0AfterPSPE = 0,
            int p1BeforePSPE = 0,
            int p1AfterPSPE = 0,
            int p0AfterPromote = 0,
            int p1AfterPromote = 0
            )
        {
            string testCaseDescription = string.Format(
                "TestCase_PSPENonMsdtc commit={0}; promote={1}; spcResponse= {2}; p0BeforePSPE={3}; p0AfterPSPE={4}; p1BeforePSPE={5}; p1AfterPSPE={6}; p0AfterPromote={7}; p1AfterPromote={8}",
                commit,
                promote,
                spcResponse,
                p0BeforePSPE,
                p0AfterPSPE,
                p1BeforePSPE,
                p1AfterPSPE,
                p0AfterPromote,
                p1AfterPromote);

            Trace("**** " + testCaseDescription + " ****");

            // It doesn't make sense to have "AfterPromote" enlistments if we aren't going to promote the transaction.
            if (!promote)
            {
                if ((p0AfterPromote > 0) || (p1AfterPromote > 0))
                {
                    Trace("Not promoting - Resetting p0AfterPromote and p1AfterPromote to 0.");
                    p0AfterPromote = 0;
                    p1AfterPromote = 0;
                }
            }

            AutoResetEvent completedEvent = new AutoResetEvent(false);

            IPromotableSinglePhaseNotification enlistment = null;
            Transaction savedTransaction = null;

            int numVolatiles = p0BeforePSPE + p0AfterPSPE + p1BeforePSPE + p1AfterPSPE + p0AfterPromote + p1AfterPromote;

            AutoResetEvent[] enlistmentDoneEvts = new AutoResetEvent[numVolatiles];
            MyEnlistment[] vols = new MyEnlistment[numVolatiles];
            for (int i = 0; i < numVolatiles; i++)
            {
                enlistmentDoneEvts[i] = new AutoResetEvent(false);
            }

            try
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    // For checking status later, outside the scope.
                    savedTransaction = Transaction.Current.Clone();

                    if (p0BeforePSPE > 0)
                    {
                        for (int i = 0; i < p0BeforePSPE; i++)
                        {
                            vols[i] = CreateVolatileEnlistment(enlistmentDoneEvts[i], null, EnlistmentOptions.EnlistDuringPrepareRequired, /*votePrepared=*/ true);
                        }
                    }

                    if (p1BeforePSPE > 0)
                    {
                        for (int i = 0; i < p1BeforePSPE; i++)
                        {
                            vols[p0BeforePSPE + i] = CreateVolatileEnlistment(enlistmentDoneEvts[p0BeforePSPE + i], null, EnlistmentOptions.None, /*votePrepared=*/ true);
                        }
                    }

                    enlistment = CreatePSPEEnlistment(NonMsdtcPromoterTests.PromoterType1,
                        NonMsdtcPromoterTests.PromotedToken1,
                        completedEvent,
                        /*nonMSDTC = */ true,
                        /*tx = */ null,
                        spcResponse,
                        /*expectRejection=*/ false
                        );

                    if (p0AfterPSPE > 0)
                    {
                        for (int i = 0; i < p0AfterPSPE; i++)
                        {
                            vols[p0BeforePSPE + p1BeforePSPE + i] = CreateVolatileEnlistment(
                                enlistmentDoneEvts[p0BeforePSPE + p1BeforePSPE + i],
                                null, EnlistmentOptions.EnlistDuringPrepareRequired, /*votePrepared=*/ true);
                        }
                    }

                    if (p1AfterPSPE > 0)
                    {
                        for (int i = 0; i < p1AfterPSPE; i++)
                        {
                            vols[p0BeforePSPE + p1BeforePSPE + p0AfterPSPE + i] = CreateVolatileEnlistment(
                                enlistmentDoneEvts[p0BeforePSPE + p1BeforePSPE + p0AfterPSPE + i],
                                null, EnlistmentOptions.None, /*votePrepared=*/ true);
                        }
                    }

                    if (promote)
                    {
                        Promote(testCaseDescription, NonMsdtcPromoterTests.PromotedToken1);

                        if (p0AfterPromote > 0)
                        {
                            for (int i = 0; i < p0AfterPromote; i++)
                            {
                                vols[p0BeforePSPE + p1BeforePSPE + p0AfterPSPE + p1AfterPSPE + i] = CreateVolatileEnlistment(
                                    enlistmentDoneEvts[p0BeforePSPE + p1BeforePSPE + p0AfterPSPE + p1AfterPSPE + i],
                                    null, EnlistmentOptions.EnlistDuringPrepareRequired, /*votePrepared=*/ true);
                            }
                        }

                        if (p1AfterPromote > 0)
                        {
                            for (int i = 0; i < p1AfterPromote; i++)
                            {
                                vols[p0BeforePSPE + p1BeforePSPE + p0AfterPSPE + p1AfterPSPE + p0AfterPromote + i] = CreateVolatileEnlistment(
                                    enlistmentDoneEvts[p0BeforePSPE + p1BeforePSPE + p0AfterPSPE + p1AfterPSPE + p0AfterPromote + i],
                                    null, EnlistmentOptions.None, /*votePrepared=*/ true);
                            }
                        }
                    }

                    if (commit)
                    {
                        ts.Complete();
                    }
                }
            }
            catch (Exception ex)
            {
                TransactionAbortedException abortedEx = ex as TransactionAbortedException;
                if ((abortedEx != null) && (spcResponse != TransactionStatus.Aborted))
                {
                    TestFailed(testCaseDescription, "The transaction aborted unexpectedly");
                    return;
                }

                TransactionInDoubtException indoubtEx = ex as TransactionInDoubtException;
                if ((indoubtEx != null) && (spcResponse != TransactionStatus.InDoubt))
                {
                    TestFailed(testCaseDescription, "The transaction was indoubt unexpectedly");
                    return;
                }

                if (spcResponse == TransactionStatus.Committed)
                {
                    Trace(string.Format("Caught unexpected exception {0}:{1}", ex.GetType().ToString(), ex.ToString()));
                    return;
                }
            }

            NonMSDTCPromoterEnlistment nonDtcEnlistment = enlistment as NonMSDTCPromoterEnlistment;
            if (nonDtcEnlistment == null)
            {
                TestFailed(testCaseDescription, "The enlistment was not a NonMSDTCPromoterEnlistment");
                return;
            }

            if (numVolatiles > 0)
            {
                for (int i = 0; i < numVolatiles; i++)
                {
                    if (!enlistmentDoneEvts[i].WaitOne(TimeSpan.FromSeconds(5)))
                    {
                        TestFailed(testCaseDescription, "Timeout waiting for enlistment outcomes");
                        return;
                    }
                }

                //if (WaitHandle.WaitAll(enlistmentDoneEvts, TimeSpan.FromSeconds(5)))
                //{

                int passCount = 0;
                for (int i = 0; i < numVolatiles; i++)
                {
                    if (commit)
                    {
                        if (((spcResponse == TransactionStatus.Committed) && vols[i].CommittedOutcome) ||
                            ((spcResponse == TransactionStatus.Aborted) && vols[i].AbortedOutcome) ||
                            ((spcResponse == TransactionStatus.InDoubt) && vols[i].InDoubtOutcome)
                           )
                        {
                            passCount++;
                        }
                    }
                    else
                    {
                        if (vols[i].AbortedOutcome)
                        {
                            passCount++;
                        }
                    }
                }
                if (passCount != numVolatiles)
                {
                    TestFailed(testCaseDescription, string.Format("{0} enlistments received an outcome of {1}", passCount, spcResponse.ToString()));
                }
                //}
                //else
                //{
                //    TestFailed(testCaseDescription, "Timeout waiting for enlistment outcomes");
                //}
            }

            if (completedEvent.WaitOne(TimeSpan.FromSeconds(5)))
            {
                if (!promote && nonDtcEnlistment.Promoted)
                {
                    TestFailed(testCaseDescription, "The enlistment promoted");
                    return;
                }

                if (promote && !nonDtcEnlistment.Promoted)
                {
                    TestFailed(testCaseDescription, "The enlistment was not promoted");
                    return;
                }

                if (commit)
                {
                    if ((spcResponse == TransactionStatus.Committed) && (nonDtcEnlistment.Aborted))
                    {
                        TestFailed(testCaseDescription, "The enlistment aborted");
                        return;
                    }
                }
                else
                {
                    if (!nonDtcEnlistment.Aborted)
                    {
                        TestFailed(testCaseDescription, "The enlistment committed");
                        return;
                    }
                }

                if (commit)
                {
                    if (savedTransaction.TransactionInformation.Status != spcResponse)
                    {
                        TestFailed(testCaseDescription, string.Format("Unexpected final transaction status of {0}", savedTransaction.TransactionInformation.Status));
                        return;
                    }
                }
                else if (!commit & savedTransaction.TransactionInformation.Status != TransactionStatus.Aborted)
                {
                    TestFailed(testCaseDescription, string.Format("Unexpected final transaction status of {0}", savedTransaction.TransactionInformation.Status));
                    return;
                }

                TestPassed();
            }
            else
            {
                TestFailed(testCaseDescription, "Timeout waiting for enlistment outcome");
            }
        }
Exemplo n.º 3
0
            public void Prepare(PreparingEnlistment preparingEnlistment)
            {
                if (_enlistDuringPrepare)
                {
                    Trace(string.Format("MyEnlistment.Prepare - attempting another enlistment with options {0}", _enlistOptions.ToString()));
                    try
                    {
                        MyEnlistment enlist2 = new MyEnlistment(
                            _secondEnlistmentCompleted,
                            /*votePrepared=*/ true,
                            /*enlistDuringPrepare=*/ false,
                            _enlistOptions);
                        this.TransactionToEnlist.EnlistVolatile(enlist2, _enlistOptions);
                        if (!_expectSuccessfulEnlist)
                        {
                            // Force rollback of the transaction because the second enlistment was unsuccessful.
                            Trace("MyEnlistment.Prepare - Force Rollback because second enlistment succeeded unexpectedly");
                            _aborted = true;
                            _outcomeReceived.Set();
                            preparingEnlistment.ForceRollback(new Exception("MyEnlistment voted ForceRollback"));
                            return;
                        }
                    }
                    catch (Exception ex)
                    {
                        if (_expectSuccessfulEnlist)
                        {
                            Trace(string.Format("MyEnlistment.Prepare - Force Rollback because second enlistment failed unexpectedly - {0}; {1}", ex.GetType().ToString(), ex.ToString()));
                            // Force rollback of the transaction because the second enlistment was unsuccessful.
                            _aborted = true;
                            _outcomeReceived.Set();
                            preparingEnlistment.ForceRollback(new Exception("MyEnlistment voted ForceRollback"));
                            return;
                        }
                    }
                }

                if (_votePrepared)
                {
                    Trace("MyEnlistment.Prepare voting Prepared");
                    preparingEnlistment.Prepared();
                }
                else
                {
                    Trace("MyEnlistment.Prepare - Force Rollback");
                    _aborted = true;
                    _outcomeReceived.Set();
                    preparingEnlistment.ForceRollback(new Exception("MyEnlistment voted ForceRollback"));
                }
            }
Exemplo n.º 4
0
        public void SimpleTransactionSuperior()
        {
            MySimpleTransactionSuperior superior = new MySimpleTransactionSuperior();
            SubordinateTransaction subTx = new SubordinateTransaction(IsolationLevel.Serializable, superior);

            AutoResetEvent durableCompleted = new AutoResetEvent(false);
            MyEnlistment durable = null;

            durable = new MyEnlistment(
                durableCompleted,
                true,
                false,
                EnlistmentOptions.None,
                /*expectSuccessfulEnlist=*/ false,
                /*secondEnlistmentCompleted=*/ null);
            durable.TransactionToEnlist = Transaction.Current;

            Assert.Throws<PlatformNotSupportedException>(() => // SubordinateTransaction promotes to MSDTC
            {
                subTx.EnlistDurable(Guid.NewGuid(), durable, EnlistmentOptions.None);
            });

            Assert.Equal(0, s_testFailures);
        }
Exemplo n.º 5
0
        public static void TestCase_EnlistDuringPrepare(bool promote,
            bool beforePromote,
            EnlistmentOptions firstOptions = EnlistmentOptions.None,
            EnlistmentOptions secondOptions = EnlistmentOptions.None,
            bool expectSecondEnlistSuccess = true
            )
        {
            string testCaseDescription = string.Format(
                "TestCase_EnlistDuringPrepare promote={0}; beforePromote={1}, firstOptions={2}, secondOptions={3}, expectSecondEnlistSuccess={4}",
                promote,
                beforePromote,
                firstOptions.ToString(),
                secondOptions.ToString(),
                expectSecondEnlistSuccess
                );

            Trace("**** " + testCaseDescription + " ****");

            AutoResetEvent volCompleted = new AutoResetEvent(false);
            AutoResetEvent vol2Completed = new AutoResetEvent(false);
            AutoResetEvent pspeCompleted = new AutoResetEvent(false);
            MyEnlistment vol = null;
            NonMSDTCPromoterEnlistment pspe = null;

            try
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    if (beforePromote)
                    {
                        vol = new MyEnlistment(
                            volCompleted,
                            true,
                            true,
                            secondOptions,
                            /*expectSuccessfulEnlist=*/ expectSecondEnlistSuccess,
                            vol2Completed);
                        vol.TransactionToEnlist = Transaction.Current;
                        Transaction.Current.EnlistVolatile(vol, firstOptions);
                    }

                    pspe = (NonMSDTCPromoterEnlistment)CreatePSPEEnlistment(NonMsdtcPromoterTests.PromoterType1,
                        NonMsdtcPromoterTests.PromotedToken1,
                        pspeCompleted,
                        /*nonMSDTC = */ true,
                        /*tx = */ null,
                        /*spcResponse=*/ TransactionStatus.Committed,
                        /*expectRejection=*/ false
                        );

                    if (promote)
                    {
                        Promote(testCaseDescription, NonMsdtcPromoterTests.PromotedToken1);

                        if (!beforePromote)
                        {
                            vol = new MyEnlistment(
                                volCompleted,
                                true,
                                true,
                                secondOptions,
                                /*expectSuccessfulEnlist=*/ expectSecondEnlistSuccess,
                                vol2Completed);
                            vol.TransactionToEnlist = Transaction.Current;
                            Transaction.Current.EnlistVolatile(vol, firstOptions);
                        }
                    }

                    ts.Complete();
                }
            }
            catch (Exception ex)
            {
                TestFailed(testCaseDescription, string.Format("Unexpected exception {0}: {1}", ex.GetType().ToString(), ex.ToString()));
                return;
            }

            if (!expectSecondEnlistSuccess)
            {
                vol2Completed.Set();
            }

            if (!volCompleted.WaitOne(TimeSpan.FromSeconds(5)) || !vol2Completed.WaitOne(TimeSpan.FromSeconds(5)) ||
                !pspeCompleted.WaitOne(TimeSpan.FromSeconds(5)))
            {
                TestFailed(testCaseDescription, "Timeout waiting for enlistment outcomes");
                return;
            }

            //if (WaitHandle.WaitAll(new WaitHandle[3] { volCompleted, vol2Completed, pspeCompleted }, TimeSpan.FromSeconds(5)))
            //{
            if (vol.AbortedOutcome)
            {
                TestFailed(testCaseDescription, "The volatile enlistment aborted unexpectedly");
            }

            if (!promote && pspe.Promoted)
            {
                TestFailed(testCaseDescription, "The enlistment promoted");
                return;
            }

            if (promote && !pspe.Promoted)
            {
                TestFailed(testCaseDescription, "The enlistment was not promoted");
                return;
            }

            if (pspe.Aborted)
            {
                TestFailed(testCaseDescription, "The pspe aborted unexpectedly");
                return;
            }

            TestPassed();
            //}
            //else
            //{
            //    TestFailed(testCaseDescription, "Timeout waiting for enlistment outcomes");
            //}


        }
Exemplo n.º 6
0
 private static MyEnlistment CreateVolatileEnlistment(
     AutoResetEvent outcomeReceived,
     Transaction tx = null,
     EnlistmentOptions options = EnlistmentOptions.None,
     bool votePrepared = true)
 {
     MyEnlistment enlistment = new MyEnlistment(outcomeReceived, votePrepared);
     Transaction txToEnlist = Transaction.Current;
     if (tx != null)
     {
         txToEnlist = tx;
     }
     txToEnlist.EnlistVolatile(enlistment, options);
     return enlistment;
 }
Exemplo n.º 7
0
        public static void TestCase_EnlistDuringPrepare(bool promote,
            bool beforePromote,
            EnlistmentOptions firstOptions = EnlistmentOptions.None,
            EnlistmentOptions secondOptions = EnlistmentOptions.None,
            bool expectSecondEnlistSuccess = true
            )
        {
            string testCaseDescription = string.Format(
                "TestCase_EnlistDuringPrepare promote={0}; beforePromote={1}, firstOptions={2}, secondOptions={3}, expectSecondEnlistSuccess={4}",
                promote,
                beforePromote,
                firstOptions.ToString(),
                secondOptions.ToString(),
                expectSecondEnlistSuccess
                );

            Trace("**** " + testCaseDescription + " ****");

            AutoResetEvent volCompleted = new AutoResetEvent(false);
            AutoResetEvent vol2Completed = new AutoResetEvent(false);
            AutoResetEvent pspeCompleted = new AutoResetEvent(false);
            MyEnlistment vol = null;
            NonMSDTCPromoterEnlistment pspe = null;

            try
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    if (beforePromote)
                    {
                        vol = new MyEnlistment(
                            volCompleted,
                            true,
                            true,
                            secondOptions,
                            /*expectSuccessfulEnlist=*/ expectSecondEnlistSuccess,
                            vol2Completed);
                        vol.TransactionToEnlist = Transaction.Current;
                        Transaction.Current.EnlistVolatile(vol, firstOptions);
                    }

                    pspe = (NonMSDTCPromoterEnlistment)CreatePSPEEnlistment(NonMsdtcPromoterTests.PromoterType1,
                        NonMsdtcPromoterTests.PromotedToken1,
                        pspeCompleted,
                        /*nonMSDTC = */ true,
                        /*tx = */ null,
                        /*spcResponse=*/ TransactionStatus.Committed,
                        /*expectRejection=*/ false
                        );

                    if (promote)
                    {
                        Promote(testCaseDescription, NonMsdtcPromoterTests.PromotedToken1);

                        if (!beforePromote)
                        {
                            vol = new MyEnlistment(
                                volCompleted,
                                true,
                                true,
                                secondOptions,
                                /*expectSuccessfulEnlist=*/ expectSecondEnlistSuccess,
                                vol2Completed);
                            vol.TransactionToEnlist = Transaction.Current;
                            Transaction.Current.EnlistVolatile(vol, firstOptions);
                        }
                    }

                    ts.Complete();
                }
            }
            catch (Exception ex)
            {
                Assert.Null(ex);
            }

            if (!expectSecondEnlistSuccess)
            {
                vol2Completed.Set();
            }

            Assert.True(volCompleted.WaitOne(TimeSpan.FromSeconds(5)) && vol2Completed.WaitOne(TimeSpan.FromSeconds(5)) &&
                pspeCompleted.WaitOne(TimeSpan.FromSeconds(5)));

            Assert.False(vol.AbortedOutcome);

            if (promote)
            {
                Assert.True(pspe.Promoted);
            }
            else
            {
                Assert.False(pspe.Promoted);
            }

            Assert.False(pspe.Aborted);

            TestPassed();
        }