2 // Tests for combination of volatile & durable resource manangers
5 // Ankit Jain <JAnkit@novell.com>
7 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
11 using System.Transactions;
12 using NUnit.Framework;
14 namespace MonoTests.System.Transactions {
17 public class EnlistTest {
21 /* Single volatile resource, SPC happens */
23 public void Vol1_Dur0 ()
25 IntResourceManager irm = new IntResourceManager (1);
27 using (TransactionScope scope = new TransactionScope ()) {
36 public void Vol1_Dur0_2PC ()
38 IntResourceManager irm = new IntResourceManager (1);
40 using (TransactionScope scope = new TransactionScope ()) {
48 /* Single volatile resource, SPC happens */
50 public void Vol1_Dur0_Fail1 ()
52 IntResourceManager irm = new IntResourceManager (1);
54 using (TransactionScope scope = new TransactionScope ()) {
57 /* Not completing this..
61 irm.Check ( 0, 0, 0, 1, 0, "irm" );
65 [ExpectedException ( typeof ( TransactionAbortedException ) )]
66 public void Vol1_Dur0_Fail2 ()
68 IntResourceManager irm = new IntResourceManager (1);
70 irm.FailPrepare = true;
72 using (TransactionScope scope = new TransactionScope ()) {
80 [ExpectedException ( typeof ( TransactionAbortedException ) )]
81 public void Vol1_Dur0_Fail3 ()
83 IntResourceManager irm = new IntResourceManager (1);
87 using (TransactionScope scope = new TransactionScope ()) {
98 /* >1 volatile, 2PC */
100 public void Vol2_Dur0_SPC ()
102 IntResourceManager irm = new IntResourceManager (1);
103 IntResourceManager irm2 = new IntResourceManager (3);
105 irm.UseSingle = true;
106 irm2.UseSingle = true;
107 using (TransactionScope scope = new TransactionScope ()) {
113 irm.Check2PC ( "irm" );
114 irm2.Check2PC ( "irm2" );
122 public void Vol0_Dur1 ()
124 IntResourceManager irm = new IntResourceManager (1);
125 irm.Volatile = false;
126 irm.UseSingle = true;
128 using (TransactionScope scope = new TransactionScope ()) {
134 irm.CheckSPC ( "irm" );
137 /* We support only 1 durable with 2PC
138 * On .net, this becomes a distributed transaction
141 [Category ("NotWorking")]
142 public void Vol0_Dur1_2PC ()
144 IntResourceManager irm = new IntResourceManager (1);
146 /* Durable resource enlisted with a IEnlistedNotification
149 irm.Volatile = false;
151 using (TransactionScope scope = new TransactionScope ()) {
159 public void Vol0_Dur1_Fail ()
161 IntResourceManager irm = new IntResourceManager ( 1 );
163 /* Durable resource enlisted with a IEnlistedNotification
166 irm.Volatile = false;
168 irm.UseSingle = true;
170 using (TransactionScope scope = new TransactionScope ()) {
176 catch (TransactionAbortedException) {
177 irm.Check ( 1, 0, 0, 0, 0, "irm" );
186 /* >1vol + 1 durable */
188 public void Vol2_Dur1 ()
190 IntResourceManager [] irm = new IntResourceManager [4];
191 irm [0] = new IntResourceManager ( 1 );
192 irm [1] = new IntResourceManager ( 3 );
193 irm [2] = new IntResourceManager ( 5 );
194 irm [3] = new IntResourceManager ( 7 );
196 irm [0].Volatile = false;
197 for ( int i = 0; i < 4; i++ )
198 irm [i].UseSingle = true;
200 using (TransactionScope scope = new TransactionScope ()) {
209 irm [0].CheckSPC ( "irm [0]" );
211 /* Volatile RMs get 2PC */
212 for (int i = 1; i < 4; i++)
213 irm [i].Check2PC ( "irm [" + i + "]" );
220 public void Vol2_Dur1_Fail1 ()
222 IntResourceManager [] irm = new IntResourceManager [4];
223 irm [0] = new IntResourceManager (1);
224 irm [1] = new IntResourceManager (3);
225 irm [2] = new IntResourceManager (5);
226 irm [3] = new IntResourceManager (7);
228 irm [0].Volatile = false;
229 irm [0].FailSPC = true;
231 for ( int i = 0; i < 4; i++ )
232 irm [i].UseSingle = true;
234 /* Durable RM irm[0] does Abort on SPC, so
235 * all volatile RMs get Rollback */
237 using (TransactionScope scope = new TransactionScope ()) {
246 catch (TransactionAbortedException) {
247 irm [0].CheckSPC ( "irm [0]" );
248 /* Volatile RMs get 2PC Prepare, and then get rolled back */
249 for (int i = 1; i < 4; i++)
250 irm [i].Check ( 0, 1, 0, 1, 0, "irm [" + i + "]" );
255 * durable doesn't complete SPC
258 [Ignore ( "Correct this test, it should throw TimeOutException or something" )]
259 public void Vol2_Dur1_Fail2 ()
261 TransactionAbortedException exception = null;
262 IntResourceManager [] irm = new IntResourceManager [4];
263 irm [0] = new IntResourceManager (1);
264 irm [1] = new IntResourceManager (3);
265 irm [2] = new IntResourceManager (5);
266 irm [3] = new IntResourceManager (7);
268 irm [0].Volatile = false;
269 irm [0].IgnoreSPC = true;
271 for ( int i = 0; i < 4; i++ )
272 irm [i].UseSingle = true;
274 /* Durable RM irm[2] does on SPC, so
275 * all volatile RMs get Rollback */
277 using (TransactionScope scope = new TransactionScope ( TransactionScopeOption.Required, new TimeSpan ( 0, 0, 5 ) )) {
286 catch (TransactionAbortedException ex) {
287 irm [0].CheckSPC ( "irm [0]" );
289 /* Volatile RMs get 2PC Prepare, and then get rolled back */
290 for (int i = 1; i < 4; i++)
291 irm [i].Check ( 0, 1, 0, 1, 0, "irm [" + i + "]" );
296 Assert.IsNotNull(exception, "Expected TransactionAbortedException not thrown!");
297 Assert.IsNotNull(exception.InnerException, "TransactionAbortedException has no inner exception!");
298 Assert.AreEqual(typeof(TimeoutException), exception.InnerException.GetType());
301 /* Same as Vol2_Dur1_Fail2, but with a volatile manager timming out */
303 [Ignore ( "Correct this test, it should throw TimeOutException or something" )]
304 public void Vol2_Dur1_Fail2b()
306 TransactionAbortedException exception = null;
307 IntResourceManager[] irm = new IntResourceManager[4];
308 irm[0] = new IntResourceManager(1);
309 irm[1] = new IntResourceManager(3);
310 irm[2] = new IntResourceManager(5);
311 irm[3] = new IntResourceManager(7);
313 irm[0].IgnoreSPC = true;
314 irm[1].Volatile = false;
316 for (int i = 0; i < 4; i++)
317 irm[i].UseSingle = true;
319 /* Durable RM irm[2] does on SPC, so
320 * all volatile RMs get Rollback */
323 using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 5)))
333 catch (TransactionAbortedException ex)
335 irm[0].CheckSPC("irm [0]");
337 /* Volatile RMs get 2PC Prepare, and then get rolled back */
338 for (int i = 1; i < 4; i++)
339 irm[i].Check(0, 1, 0, 1, 0, "irm [" + i + "]");
344 Assert.IsNotNull(exception, "Expected TransactionAbortedException not thrown!");
345 Assert.IsNotNull(exception.InnerException, "TransactionAbortedException has no inner exception!");
346 Assert.AreEqual(typeof(TimeoutException), exception.InnerException.GetType());
350 * Volatile fails Prepare
353 public void Vol2_Dur1_Fail3 ()
355 IntResourceManager [] irm = new IntResourceManager [4];
356 irm [0] = new IntResourceManager ( 1 );
357 irm [1] = new IntResourceManager ( 3 );
358 irm [2] = new IntResourceManager ( 5 );
359 irm [3] = new IntResourceManager ( 7 );
361 irm [0].Volatile = false;
362 irm [2].FailPrepare = true;
364 for ( int i = 0; i < 4; i++ )
365 irm [i].UseSingle = true;
367 /* Durable RM irm[2] does on SPC, so
368 * all volatile RMs get Rollback */
370 using (TransactionScope scope = new TransactionScope ()) {
379 catch (TransactionAbortedException) {
380 irm [0].Check ( 0, 0, 0, 1, 0, "irm [0]");
382 /* irm [1] & [2] get prepare,
383 * [2] -> ForceRollback,
384 * [1] & [3] get rollback,
385 * [0](durable) gets rollback */
386 irm [1].Check ( 0, 1, 0, 1, 0, "irm [1]" );
387 irm [2].Check ( 0, 1, 0, 0, 0, "irm [2]" );
388 irm [3].Check ( 0, 0, 0, 1, 0, "irm [3]" );
393 Assert.Fail ( "Expected TransactionAbortedException" );
397 public void Vol2_Dur1_Fail4 ()
399 IntResourceManager [] irm = new IntResourceManager [2];
400 irm [0] = new IntResourceManager ( 1 );
401 irm [1] = new IntResourceManager ( 3 );
403 irm [0].Volatile = false;
404 irm [0].FailSPC = true;
405 irm [0].FailWithException = true;
407 for ( int i = 0; i < 2; i++ )
408 irm [i].UseSingle = true;
410 /* Durable RM irm[2] does on SPC, so
411 * all volatile RMs get Rollback */
413 using ( TransactionScope scope = new TransactionScope () ) {
420 catch ( TransactionAbortedException e) {
421 Assert.IsNotNull ( e.InnerException, "Expected e.InnerException == NotSupportedException, but got None");
422 Assert.AreEqual ( typeof ( NotSupportedException ), e.InnerException.GetType (), "Expected e.InnerException == NotSupportedException, but got " + e.GetType () );
424 irm [0].Check ( 1, 0, 0, 0, 0, "irm [0]" );
425 irm [1].Check ( 0, 1, 0, 1, 0, "irm [1]" );
429 Assert.Fail ( "Expected TransactionAbortedException" );
433 public void Vol2_Dur1_Fail5 ()
435 CommittableTransaction ct = new CommittableTransaction ();
436 IntResourceManager [] irm = new IntResourceManager [2];
437 irm [0] = new IntResourceManager ( 1 );
438 irm [1] = new IntResourceManager ( 3 );
440 Transaction.Current = ct;
441 irm [0].Volatile = false;
442 irm [0].FailSPC = true;
443 irm [0].FailWithException = true;
445 for ( int i = 0; i < 2; i++ )
446 irm [i].UseSingle = true;
448 /* Durable RM irm[2] does on SPC, so
449 * all volatile RMs get Rollback */
451 using ( TransactionScope scope = new TransactionScope () ) {
461 catch ( TransactionAbortedException e ) {
462 Assert.IsNotNull ( e.InnerException, "Expected e.InnerException == NotSupportedException, but got None" );
463 Assert.AreEqual ( typeof ( NotSupportedException ), e.InnerException.GetType (), "Expected e.InnerException == NotSupportedException, but got " + e.GetType () );
465 irm [0].Check ( 1, 0, 0, 0, 0, "irm [0]" );
466 irm [1].Check ( 0, 1, 0, 1, 0, "irm [1]" );
470 catch (InvalidOperationException x ) {
471 Assert.IsNull ( x.InnerException);
472 Transaction.Current = null;
475 Assert.Fail ( "Should not be reached" );
478 Assert.Fail ( "Expected TransactionAbortedException" );
485 * > 1 durable, On .net this becomes a distributed transaction
486 * We don't support this in mono yet.
489 [Category ("NotWorking")]
490 public void Vol0_Dur2 ()
492 IntResourceManager [] irm = new IntResourceManager [2];
493 irm [0] = new IntResourceManager ( 1 );
494 irm [1] = new IntResourceManager ( 3 );
496 irm [0].Volatile = false;
497 irm [1].Volatile = false;
499 for ( int i = 0; i < 2; i++ )
500 irm [i].UseSingle = true;
502 using (TransactionScope scope = new TransactionScope ()) {
511 public void TransactionDispose ()
513 CommittableTransaction ct = new CommittableTransaction ();
514 IntResourceManager irm = new IntResourceManager (1);
515 irm.Volatile = false;
518 irm.Check (0, 0, 0, 0, "Dispose transaction");
522 public void TransactionDispose2 ()
524 CommittableTransaction ct = new CommittableTransaction ();
525 IntResourceManager irm = new IntResourceManager (1);
527 Transaction.Current = ct;
533 Transaction.Current = null;
536 irm.Check (0, 0, 1, 0, "Dispose transaction");
537 Assert.AreEqual (1, irm.Value);
541 public void TransactionDispose3 ()
543 CommittableTransaction ct = new CommittableTransaction ();
544 IntResourceManager irm = new IntResourceManager (1);
547 Transaction.Current = ct;
552 Transaction.Current = null;
555 irm.Check (1, 1, 0, 0, "Dispose transaction");
556 Assert.AreEqual (5, irm.Value);
560 public void TransactionCompleted_Committed ()
563 using (var ts = new TransactionScope ())
565 var tr = Transaction.Current;
566 tr.TransactionCompleted += (s, e) => called = true;
570 Assert.IsTrue (called, "TransactionCompleted event handler not called!");
574 public void TransactionCompleted_Rollback ()
577 using (var ts = new TransactionScope ())
579 var tr = Transaction.Current;
580 tr.TransactionCompleted += (s, e) => called = true;
581 // Not calling ts.Complete() on purpose..
584 Assert.IsTrue (called, "TransactionCompleted event handler not called!");