1 // 2 // ResourceManager representing an integer, used by other test cases 3 // 4 // Author: 5 // Ankit Jain <JAnkit@novell.com> 6 // 7 // Copyright (C) 2006 Novell, Inc (http://www.novell.com) 8 // 9 10 using System; 11 using System.Collections.Generic; 12 using System.Text; 13 using System.Transactions; 14 using NUnit.Framework; 15 16 namespace MonoTests.System.Transactions 17 { 18 public class IntResourceManager 19 { IntResourceManager(int value)20 public IntResourceManager (int value) 21 { 22 actual = value; 23 guid = Guid.NewGuid (); 24 } 25 26 private int actual; 27 private int tmpValue; 28 private Transaction transaction = null; 29 30 public int NumPrepare = 0; 31 public int NumRollback = 0; 32 public int NumCommit = 0; 33 public int NumInDoubt = 0; 34 public int NumSingle = 0; 35 36 public int NumInitialize = 0; 37 public int NumPromote = 0; 38 public int NumEnlistFailed = 0; 39 40 public ResourceManagerType Type = ResourceManagerType.Volatile; 41 public bool FailPrepare = false; 42 public bool FailWithException = false; 43 public bool IgnorePrepare = false; 44 public bool IgnoreSPC = false; 45 public bool FailSPC = false; 46 public bool FailCommit = false; 47 public bool FailRollback = false; 48 public bool UseSingle = false; 49 public Exception ThrowThisException = null; 50 51 Guid guid; 52 53 public int Actual { 54 get { return actual; } 55 } 56 57 public int Value { 58 get { return transaction == null ? actual : tmpValue; } 59 set 60 { 61 if (Transaction.Current == null) { 62 /* Not in a transaction */ 63 actual = value; 64 return; 65 } 66 /* FIXME: Do what in this case? */ 67 if (transaction != null) 68 Console.WriteLine ("WARNING: Setting value more than once"); 69 70 if (transaction != Transaction.Current) { 71 transaction = Transaction.Current; 72 73 if ( Type == ResourceManagerType.Promotable ) { 74 transaction.EnlistPromotableSinglePhase(new PromotableSinglePhaseNotification ( this )); 75 } else if (UseSingle) { 76 SinglePhaseNotification enlistment = new SinglePhaseNotification ( this ); 77 if ( Type == ResourceManagerType.Volatile ) 78 transaction.EnlistVolatile ( enlistment, EnlistmentOptions.None ); 79 else 80 transaction.EnlistDurable ( guid, enlistment, EnlistmentOptions.None ); 81 } else { 82 EnlistmentNotification enlistment = new EnlistmentNotification ( this ); 83 if ( Type == ResourceManagerType.Volatile ) 84 transaction.EnlistVolatile ( enlistment, EnlistmentOptions.None ); 85 else 86 transaction.EnlistDurable ( guid, enlistment, EnlistmentOptions.None ); 87 } 88 } 89 tmpValue = value; 90 } 91 } 92 Commit()93 public void Commit () 94 { 95 actual = tmpValue; 96 transaction = null; 97 } 98 Rollback()99 public void Rollback () 100 { 101 transaction = null; 102 } 103 CheckSPC( string msg )104 public void CheckSPC ( string msg ) 105 { 106 Check ( 1, 0, 0, 0, 0, 0, 0, msg ); 107 } 108 Check2PC( string msg)109 public void Check2PC ( string msg) 110 { 111 Check ( 0, 1, 1, 0, 0, 0, 0, msg ); 112 } 113 Check( int s, int p, int c, int r, int d, int i, int pr, string msg )114 public void Check ( int s, int p, int c, int r, int d, int i, int pr, string msg ) 115 { 116 Assert.AreEqual ( s, NumSingle, msg + ": NumSingle" ); 117 Assert.AreEqual ( p, NumPrepare, msg + ": NumPrepare" ); 118 Assert.AreEqual ( c, NumCommit, msg + ": NumCommit" ); 119 Assert.AreEqual ( r, NumRollback, msg + ": NumRollback" ); 120 Assert.AreEqual ( d, NumInDoubt, msg + ": NumInDoubt" ); 121 Assert.AreEqual ( i, NumInitialize, msg + ": NumInitialize" ); 122 Assert.AreEqual ( pr, NumPromote, msg + ": NumPromote" ); 123 } 124 125 /* Used for volatile RMs */ Check( int p, int c, int r, int d, string msg )126 public void Check ( int p, int c, int r, int d, string msg ) 127 { 128 Check ( 0, p, c, r, d, 0, 0, msg ); 129 } 130 } 131 132 public class EnlistmentNotification : IEnlistmentNotification { 133 protected IntResourceManager resource; 134 EnlistmentNotification( IntResourceManager resource )135 public EnlistmentNotification ( IntResourceManager resource ) 136 { 137 this.resource = resource; 138 } 139 Prepare( PreparingEnlistment preparingEnlistment )140 public void Prepare ( PreparingEnlistment preparingEnlistment ) 141 { 142 resource.NumPrepare++; 143 if ( resource.IgnorePrepare ) 144 return; 145 146 if ( resource.FailPrepare ) { 147 if (resource.FailWithException) 148 preparingEnlistment.ForceRollback ( resource.ThrowThisException ?? new NotSupportedException () ); 149 else 150 preparingEnlistment.ForceRollback (); 151 } else { 152 preparingEnlistment.Prepared (); 153 } 154 } 155 Commit( Enlistment enlistment )156 public void Commit ( Enlistment enlistment ) 157 { 158 resource.NumCommit++; 159 if (resource.FailCommit) 160 { 161 if (resource.FailWithException) 162 throw (resource.ThrowThisException ?? new NotSupportedException()); 163 else 164 return; 165 } 166 167 resource.Commit (); 168 enlistment.Done (); 169 } 170 Rollback( Enlistment enlistment )171 public void Rollback ( Enlistment enlistment ) 172 { 173 resource.NumRollback++; 174 if (resource.FailRollback) 175 { 176 if (resource.FailWithException) 177 throw (resource.ThrowThisException ?? new NotSupportedException()); 178 else 179 return; 180 } 181 182 resource.Rollback (); 183 } 184 InDoubt( Enlistment enlistment )185 public void InDoubt ( Enlistment enlistment ) 186 { 187 resource.NumInDoubt++; 188 throw new Exception ( "IntResourceManager.InDoubt is not implemented." ); 189 } 190 } 191 192 public class SinglePhaseNotification : EnlistmentNotification, ISinglePhaseNotification 193 { SinglePhaseNotification( IntResourceManager resource )194 public SinglePhaseNotification ( IntResourceManager resource ) 195 : base ( resource ) 196 { 197 } 198 SinglePhaseCommit( SinglePhaseEnlistment enlistment )199 public void SinglePhaseCommit ( SinglePhaseEnlistment enlistment ) 200 { 201 resource.NumSingle++; 202 if ( resource.IgnoreSPC ) 203 return; 204 205 if ( resource.FailSPC ) { 206 if ( resource.FailWithException ) 207 enlistment.Aborted ( resource.ThrowThisException ?? new NotSupportedException () ); 208 else 209 enlistment.Aborted (); 210 } 211 else { 212 resource.Commit (); 213 enlistment.Committed (); 214 } 215 } 216 } 217 218 public class PromotableSinglePhaseNotification : SinglePhaseNotification, IPromotableSinglePhaseNotification 219 { PromotableSinglePhaseNotification( IntResourceManager resource )220 public PromotableSinglePhaseNotification ( IntResourceManager resource ) 221 : base( resource ) 222 { 223 } 224 Initialize()225 public void Initialize () 226 { 227 resource.NumInitialize++; 228 } 229 Rollback( SinglePhaseEnlistment enlistment )230 public void Rollback ( SinglePhaseEnlistment enlistment ) 231 { 232 resource.NumRollback++; 233 resource.Rollback (); 234 } 235 Promote()236 public byte [] Promote () 237 { 238 resource.NumPromote++; 239 return new byte[0]; 240 } 241 } 242 243 public enum ResourceManagerType { Volatile, Durable, Promotable }; 244 } 245 246