/* * SubSonic - http://subsonicproject.com * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. */ using System.ServiceProcess; using System.Transactions; using MbUnit.Framework; using Northwind; namespace SubSonic.Tests { /// /// Summary for the TransactionTests class /// [TestFixture] public class TransactionTests { /// /// /// private readonly MsDtcService msdtc = new MsDtcService(); /// /// Tests the fixture set up. /// [TestFixtureSetUp] public void TestFixtureSetUp() { msdtc.Start(); } /// /// Tests the fixture tear down. /// [TestFixtureTearDown] public void TestFixtureTearDown() { msdtc.Revert(); } /// /// Transaction_s the rollback product. /// [Test] public void Transaction_RollbackProduct() { //use the product object to test the transaction scope using(TransactionScope scope = new TransactionScope()) { UpdateProduct(1, "20 pounds"); UpdateProduct(2, "20 pounds"); UpdateProduct(3, "20 pounds"); } //the saves shouldn't be committed, hopefully! Product pVal = new Product(1); Assert.IsTrue(pVal.QuantityPerUnit != "20 pounds"); } /// /// Transaction_s the commit product. /// [Test] public void Transaction_CommitProduct() { using(TransactionScope scope = new TransactionScope()) { //try //{ UpdateProduct(1, "10 boxes x 30 bags"); UpdateProduct(2, "24 - 42 oz bottles"); UpdateProduct(3, "12 - 5500 ml bottles"); scope.Complete(); //} //catch(System.Data.SqlClient.SqlException x) //{ // //trap/trace/log as needed // throw x; //} } //the saves shouldn't be committed, hopefully! Product pVal = new Product(1); Assert.AreEqual("10 boxes x 30 bags", pVal.QuantityPerUnit); //set them back UpdateProduct(1, "10 boxes x 20 bags"); UpdateProduct(2, "24 - 12 oz bottles"); UpdateProduct(3, "12 - 550 ml bottles"); } /// /// Updates the product. /// /// The product id. /// The quantity per unit. private static void UpdateProduct(int productId, string quantityPerUnit) { Product p1 = new Product(productId); p1.QuantityPerUnit = quantityPerUnit; p1.UnitPrice = 50; p1.Save("Unit Test"); } } /// /// Summary for the MsDtcService class /// public class MsDtcService { private readonly ServiceControllerStatus _originalDtcStatus; // instantiate ServiceController each time to get the correct Status private ServiceController serviceController; /// /// Initializes a new instance of the class. /// public MsDtcService() { _originalDtcStatus = Controller.Status; } /// /// Gets the controller. /// /// The controller. public ServiceController Controller { get { if(serviceController == null) serviceController = new ServiceController("MSDTC"); return serviceController; } } /// /// Starts this instance. /// public void Start() { if(Controller.Status != ServiceControllerStatus.Running && Controller.Status != ServiceControllerStatus.StartPending) Controller.Start(); Controller.WaitForStatus(ServiceControllerStatus.Running); } /// /// Stops this instance. /// public void Stop() { if(Controller.Status == ServiceControllerStatus.Stopped) return; if(Controller.Status != ServiceControllerStatus.StopPending) Controller.Stop(); Controller.WaitForStatus(ServiceControllerStatus.Stopped); } /// /// Pauses this instance. /// public void Pause() { if(Controller.Status != ServiceControllerStatus.Paused && Controller.Status != ServiceControllerStatus.PausePending) { if(Controller.Status != ServiceControllerStatus.Running && Controller.Status != ServiceControllerStatus.StartPending) Controller.Start(); Controller.Pause(); } Controller.WaitForStatus(ServiceControllerStatus.Paused); } /// /// Reverts this instance. /// public void Revert() { switch(_originalDtcStatus) { case ServiceControllerStatus.Stopped: Stop(); break; case ServiceControllerStatus.Paused: case ServiceControllerStatus.PausePending: Pause(); break; case ServiceControllerStatus.ContinuePending: case ServiceControllerStatus.Running: case ServiceControllerStatus.StartPending: Start(); break; } } } }