Esempio n. 1
0
        public void TestAmbientManagedFirstEntry()
        {
            if (!EnvironmentSupportsTransactions)
            {
                Assert.Inconclusive("Cannot test transactions in this environment");
                return;
            }
            Repository.Settings.StorageTransactionSettings = StorageTransactionSettings.RequireTransactions;

            TransactionSubscriber  subscriber = new TransactionSubscriber();
            IFileSystemTransaction transaction;

            using (TransactionScope masterScope = new TransactionScope())
            {
                using (var scope = StorageTransactionScope.Create(Repository))
                {
                    Assert.AreEqual(1, StorageTransactionScope.ScopeNestLevel);

                    Assert.IsTrue(scope.HasChangedContext, "Scope must have changed context");
                    Assert.IsFalse(scope.IsTransactionOwner, "Transaction must be slave under managed");
                    Assert.IsFalse(scope.ToBeDisposed, "Scope having created slave transaction must not be disposing");
                    Assert.IsNotNull(AmbientTransaction, "Context not set");
                    Assert.AreSame(AmbientTransaction, scope.UnderlyingTransaction, "Underlying transaction is not in sync with context");
                    Assert.IsTrue(scope.UnderlyingTransaction.IsActive, "Transaction must be active in this scope");

                    Assert.IsFalse(scope.UnderlyingTransaction.Unsubscribe(subscriber), "Unsubscribing not yet subscribed returned true");
                    scope.UnderlyingTransaction.Subscribe(subscriber);
                    transaction = scope.UnderlyingTransaction;

                    Assert.Throws(
                        Is.InstanceOf <InvalidOperationException>()
                        , () => transaction.Commit(), "Committing slave transaction must throw InvalidOperationException");

                    Assert.IsFalse(scope.ToBeDisposed, "Scope turned disposing after transaction detached");
                    Assert.IsFalse(scope.IsTransactionOwner);
                }

                Assert.AreEqual(0, StorageTransactionScope.ScopeNestLevel);

                Assert.IsTrue(transaction.IsActive, "Detached transaction must remain active after disposing scope");
                Assert.AreEqual(0, subscriber.TimesNotified, "Disposing detached scope must not result in notification");
                Assert.IsNull(KtmTransaction.Current, "The scope was disposed and must have restored context");

                using (var scope = StorageTransactionScope.Create(Repository, transaction))
                {
                    Assert.AreEqual(1, StorageTransactionScope.ScopeNestLevel);

                    Assert.AreSame(transaction, scope.UnderlyingTransaction, "Underlying transaction is not what was explicitly assigned");
                    Assert.IsTrue(scope.HasChangedContext, "Scope must have changed context");
                    Assert.IsFalse(scope.IsTransactionOwner, "Transaction must be slave under managed");
                    Assert.IsFalse(scope.ToBeDisposed, "Scope must not be disposing as explicitly specified when creating");
                    Assert.IsNotNull(AmbientTransaction, "Context not set");
                    Assert.AreSame(AmbientTransaction, scope.UnderlyingTransaction, "Underlying transaction is not in sync with context");
                    Assert.IsTrue(scope.UnderlyingTransaction.IsActive, "Transaction must be active in this scope");

                    scope.UnderlyingTransaction.Subscribe(subscriber);
                }

                int level = StorageTransactionScope.ScopeNestLevel;
                Assert.AreEqual(0, StorageTransactionScope.ScopeNestLevel);

                Assert.IsTrue(transaction.IsActive, "Detached transaction must remain active after disposing scope");
                Assert.AreEqual(0, subscriber.TimesNotified, "Scope was not to dispose or commit transaction");
                Assert.IsNull(AmbientTransaction, "The scope was disposed and must have restored context");

                masterScope.Complete();

                Assume.That(transaction.IsActive && subscriber.TimesNotified == 0);
            }

            System.Threading.Thread.Sleep(50);

            Assert.IsFalse(transaction.IsActive, "Master transaction was committed, KTM must be committed too");
            Assert.AreEqual(1, subscriber.TimesNotified, "Master transaction was committed, must have recieved 1 notification");
            Assert.IsTrue(subscriber.Committed, "Transaction must have beed reported committed.");

            Assert.Throws(
                Is.InstanceOf <InvalidOperationException>()
                , () => transaction.Subscribe(subscriber), "Subscribing to inactive transaction must throw exception");
        }
        public void TestRepeatedReuseSlave()
        {
            if (!EnvironmentSupportsTransactions)
            {
                Assert.Inconclusive("Cannot test transactions in this environment");
            }
            else
            {
                Assume.That(!FileSystemProvider.IsStorageAmbientTransactionActive);

                Repository.Settings.StorageTransactionSettings = StorageTransactionSettings.RequireTransactions;

                TransactionSubscriber  subscriber = new TransactionSubscriber();
                IFileSystemTransaction transaction;

                LongSlaveTransactionManager tman = new LongSlaveTransactionManager(Repository, subscriber);

                using (TransactionScope masterScope = new TransactionScope())
                {
                    using (var scope = tman.GetTransactionScope())
                    {
                        Assert.IsTrue(scope.HasChangedContext);
                        Assert.IsFalse(scope.IsNullScope);
                        Assert.IsFalse(scope.IsTransactionOwner);
                        Assert.IsFalse(scope.NoTransaction);
                        Assert.AreSame(AmbientTransaction, tman.PendingTransaction);
                        Assert.AreSame(scope.UnderlyingTransaction, tman.PendingTransaction);

                        Assert.IsTrue(tman.CanIOTransactionSpanMultipleRepositoryCalls);

                        Assert.IsTrue(tman.IsTransactionPending());

                        Assert.AreEqual(1, StorageTransactionScope.ScopeNestLevel);
                        transaction = AmbientTransaction;
                    }

                    Assert.AreEqual(0, StorageTransactionScope.ScopeNestLevel);
                    Assert.IsNull(AmbientTransaction);
                    Assert.IsNotNull(tman.PendingTransaction);
                    Assert.IsFalse(tman.CanIOTransactionSpanMultipleRepositoryCalls, "No ambientr transaction here");

                    for (int n = 0; n < 10; ++n)
                    {
                        using (var scope = tman.GetTransactionScope())
                        {
                            Assert.IsTrue(scope.HasChangedContext);
                            Assert.IsFalse(scope.IsNullScope);
                            Assert.IsFalse(scope.IsTransactionOwner);
                            Assert.IsFalse(scope.NoTransaction);

                            Assert.AreSame(transaction, tman.PendingTransaction);
                            Assert.AreSame(AmbientTransaction, tman.PendingTransaction);
                            Assert.AreSame(scope.UnderlyingTransaction, tman.PendingTransaction);

                            Assert.IsTrue(tman.CanIOTransactionSpanMultipleRepositoryCalls);

                            Assert.IsTrue(tman.IsTransactionPending());

                            Assert.AreEqual(1, StorageTransactionScope.ScopeNestLevel);
                            transaction = AmbientTransaction;
                        }
                        Assert.AreEqual(0, StorageTransactionScope.ScopeNestLevel);
                        Assert.IsNull(AmbientTransaction);
                        Assert.IsNotNull(tman.PendingTransaction);
                        Assert.IsFalse(tman.CanIOTransactionSpanMultipleRepositoryCalls, "No ambientr transaction here");
                    }

                    //masterScope.Complete();
                }                 // using (TransactionScope masterScope = new TransactionScope())

                System.Threading.Thread.Sleep(50);

                Console.WriteLine("About to test times notified");

                Assert.AreEqual(1, subscriber.TimesNotified, "Only 1 storage transaction must have been instantiated and therefore 1 notification received");
                Assert.IsFalse(subscriber.Committed, "Master scope has not been completed");
                //Assert.IsFalse(transaction.IsActive);

                Assert.IsNull(tman.PendingTransaction, "Must have received notification and reset pending transaction");
                Assert.IsFalse(tman.CanIOTransactionSpanMultipleRepositoryCalls, "There should be no ambient transaction here at all");

                tman.Dispose();

                Assert.Throws <ObjectDisposedException>(() => tman.GetTransactionScope());
            }
        }