New test.
[mono.git] / mcs / class / System.Transactions / Test / TransactionScopeTest.cs
1 //
2 // Unit tests for TransactionScope and Implicit/Explicit use of
3 // Transactions
4 //
5 // Author:
6 //      Ankit Jain      <JAnkit@novell.com>
7 //
8 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
9 //
10
11 using System;
12 using NUnit.Framework;
13 using System.Transactions;
14
15 namespace MonoTests.System.Transactions
16 {
17         [TestFixture]
18         public class TransactionScopeTest
19         {
20                 [Test]
21                 public void TransactionScopeCommit ()
22                 {
23                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
24                         using (TransactionScope scope = new TransactionScope ()) {
25                                 Assert.IsNotNull (Transaction.Current, "Ambient transaction does not exist");
26                                 Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status);
27                                 
28                                 scope.Complete ();
29                         }
30                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (after)");
31                 }
32
33                 [Test]
34                 public void TransactionScopeAbort ()
35                 {
36                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
37                         IntResourceManager irm = new IntResourceManager (1);
38                         using (TransactionScope scope = new TransactionScope ()) {
39                                 Assert.IsNotNull (Transaction.Current, "Ambient transaction does not exist");
40                                 Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status, "transaction is not active");
41
42                                 irm.Value = 2;
43                                 /* Not completing scope here */
44                         }
45                         irm.Check ( 0, 0, 1, 0, "irm");
46                         Assert.AreEqual (1, irm.Value);
47                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
48                 }
49
50                 [Test]
51                 [ExpectedException (typeof (InvalidOperationException))]
52                 public void TransactionScopeCompleted1 ()
53                 {
54                         using (TransactionScope scope = new TransactionScope ()) {
55                                 scope.Complete ();
56                                 /* Can't access ambient transaction after scope.Complete */
57                                 TransactionStatus status = Transaction.Current.TransactionInformation.Status;
58                         }
59                 }
60
61                 [Test]
62                 [ExpectedException (typeof (InvalidOperationException))]
63                 public void TransactionScopeCompleted2 ()
64                 {
65                         using (TransactionScope scope = new TransactionScope ()) {
66                                 scope.Complete ();
67                                 Transaction.Current = Transaction.Current;
68                         }
69                 }
70
71                 [Test]
72                 [ExpectedException (typeof (InvalidOperationException))]
73                 public void TransactionScopeCompleted3 ()
74                 {
75                         using (TransactionScope scope = new TransactionScope ()) {
76                                 scope.Complete ();
77                                 scope.Complete ();
78                         }
79                 }
80
81                 #region NestedTransactionScope tests
82                 [Test]
83                 public void NestedTransactionScope1 ()
84                 {
85                         IntResourceManager irm = new IntResourceManager (1);
86
87                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
88                         using (TransactionScope scope = new TransactionScope ()) {
89                                 irm.Value = 2;
90
91                                 /* Complete this scope */
92                                 scope.Complete ();
93                         }
94
95                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
96                         /* Value = 2, got committed */
97                         Assert.AreEqual (irm.Value, 2, "#1");
98                         irm.Check ( 1, 1, 0, 0, "irm" );
99                 }
100
101                 [Test]
102                 public void NestedTransactionScope2 ()
103                 {
104                         IntResourceManager irm = new IntResourceManager (1);
105                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
106                         using (TransactionScope scope = new TransactionScope ()) {
107                                 irm.Value = 2;
108
109                                 /* Not-Completing this scope */
110                         }
111
112                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
113                         /* Value = 2, got rolledback */
114                         Assert.AreEqual (irm.Value, 1, "#2");
115                         irm.Check ( 0, 0, 1, 0, "irm" );
116                 }
117
118                 [Test]
119                 public void NestedTransactionScope3 ()
120                 {
121                         IntResourceManager irm = new IntResourceManager (1);
122                         IntResourceManager irm2 = new IntResourceManager (10);
123
124                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
125                         using (TransactionScope scope = new TransactionScope ()) {
126                                 irm.Value = 2;
127
128                                 using (TransactionScope scope2 = new TransactionScope ()) {
129                                         irm2.Value = 20;
130
131                                         scope2.Complete ();
132                                 }
133
134                                 scope.Complete ();
135                         }
136
137                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
138                         /* Both got committed */
139                         Assert.AreEqual (irm.Value, 2, "#3");
140                         Assert.AreEqual (irm2.Value, 20, "#4");
141                         irm.Check ( 1, 1, 0, 0, "irm" );
142                         irm2.Check ( 1, 1, 0, 0, "irm2" );
143                 }
144
145                 [Test]
146                 public void NestedTransactionScope4 ()
147                 {
148                         IntResourceManager irm = new IntResourceManager (1);
149                         IntResourceManager irm2 = new IntResourceManager (10);
150
151                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
152                         using (TransactionScope scope = new TransactionScope ()) {
153                                 irm.Value = 2;
154
155                                 using (TransactionScope scope2 = new TransactionScope ()) {
156                                         irm2.Value = 20;
157
158                                         /* Inner Tx not completed, Tx should get rolled back */
159                                         //scope2.Complete();
160                                 }
161                                 /* Both rolledback */
162                                 irm.Check ( 0, 0, 1, 0, "irm" );
163                                 irm2.Check ( 0, 0, 1, 0, "irm2" );
164                                 Assert.AreEqual (TransactionStatus.Aborted, Transaction.Current.TransactionInformation.Status, "#5");
165                                 //scope.Complete ();
166                         }
167
168                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
169
170                         Assert.AreEqual (irm.Value, 1, "#6");
171                         Assert.AreEqual (irm2.Value, 10, "#7");
172                         irm.Check ( 0, 0, 1, 0, "irm" );
173                 }
174
175                 [Test]
176                 public void NestedTransactionScope5 ()
177                 {
178                         IntResourceManager irm = new IntResourceManager (1);
179                         IntResourceManager irm2 = new IntResourceManager (10);
180
181                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
182                         using (TransactionScope scope = new TransactionScope ()) {
183                                 irm.Value = 2;
184
185                                 using (TransactionScope scope2 = new TransactionScope ()) {
186                                         irm2.Value = 20;
187                                         scope2.Complete ();
188                                 }
189
190                                 Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status, "#8");
191                                 /* Not completing outer scope
192                                 scope.Complete (); */
193                         }
194
195                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
196
197                         Assert.AreEqual (irm.Value, 1, "#9");
198                         Assert.AreEqual (irm2.Value, 10, "#10");
199                         irm.Check ( 0, 0, 1, 0, "irm" );
200                         irm2.Check ( 0, 0, 1, 0, "irm2" );
201                 }
202
203                 [Test]
204                 public void NestedTransactionScope6 ()
205                 {
206                         IntResourceManager irm = new IntResourceManager (1);
207                         IntResourceManager irm2 = new IntResourceManager (10);
208
209                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
210                         using (TransactionScope scope = new TransactionScope ()) {
211                                 irm.Value = 2;
212
213                                 using (TransactionScope scope2 = new TransactionScope (TransactionScopeOption.RequiresNew)) {
214                                         irm2.Value = 20;
215                                         scope2.Complete ();
216                                 }
217                                 /* vr2, committed */
218                                 irm2.Check ( 1, 1, 0, 0, "irm2" );
219                                 Assert.AreEqual (irm2.Value, 20);
220
221                                 Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status, "#11");
222
223                                 scope.Complete ();
224                         }
225
226                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
227                         Assert.AreEqual (irm.Value, 2, "#12");
228                         irm.Check ( 1, 1, 0, 0, "irm" );
229                 }
230
231                 [Test]
232                 public void NestedTransactionScope7 ()
233                 {
234                         IntResourceManager irm = new IntResourceManager (1);
235                         IntResourceManager irm2 = new IntResourceManager (10);
236
237                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
238                         using (TransactionScope scope = new TransactionScope ()) {
239                                 irm.Value = 2;
240
241                                 using (TransactionScope scope2 = new TransactionScope (TransactionScopeOption.RequiresNew)) {
242                                         irm2.Value = 20;
243                                         /* Not completing 
244                                          scope2.Complete();*/
245                                 }
246
247                                 /* irm2, rolled back*/
248                                 irm2.Check ( 0, 0, 1, 0, "irm2" );
249                                 Assert.AreEqual (irm2.Value, 10, "#13");
250
251                                 Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status, "#14");
252
253                                 scope.Complete ();
254                         }
255
256                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
257                         /* ..But irm got committed */
258                         Assert.AreEqual (irm.Value, 2, "#15");
259                         irm.Check ( 1, 1, 0, 0, "irm" );
260                 }
261
262                 [Test]
263                 public void NestedTransactionScope8 ()
264                 {
265                         IntResourceManager irm = new IntResourceManager (1);
266                         IntResourceManager irm2 = new IntResourceManager (10);
267
268                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
269                         using (TransactionScope scope = new TransactionScope ()) {
270                                 irm.Value = 2;
271
272                                 using (TransactionScope scope2 = new TransactionScope (TransactionScopeOption.Suppress)) {
273                                         /* Not transactional, so this WONT get committed */
274                                         irm2.Value = 20;
275                                         scope2.Complete ();
276                                 }
277                                 irm2.Check ( 0, 0, 0, 0, "irm2" );
278                                 Assert.AreEqual (20, irm2.Value, "#16");
279                                 Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status, "#17");
280
281                                 scope.Complete ();
282                         }
283
284                         Assert.IsNull (Transaction.Current, "Ambient transaction exists");
285                         Assert.AreEqual (irm.Value, 2, "#18");
286                         irm.Check ( 1, 1, 0, 0, "irm" );
287                 }
288
289                 [Test]
290                 public void NestedTransactionScope8a ()
291                 {
292                         IntResourceManager irm = new IntResourceManager ( 1 );
293                         IntResourceManager irm2 = new IntResourceManager ( 10 );
294
295                         Assert.IsNull ( Transaction.Current, "Ambient transaction exists" );
296                         using (TransactionScope scope = new TransactionScope (TransactionScopeOption.Suppress )) {
297                                 irm.Value = 2;
298
299                                 using (TransactionScope scope2 = new TransactionScope ()) {
300                                         irm2.Value = 20;
301                                         scope2.Complete ();
302                                 }
303                                 irm2.Check ( 1, 1, 0, 0, "irm2" );
304                                 Assert.AreEqual ( 20, irm2.Value, "#16a" );
305
306                                 scope.Complete ();
307                         }
308
309                         Assert.IsNull ( Transaction.Current, "Ambient transaction exists" );
310                         Assert.AreEqual ( 2, irm.Value, "#18a" );
311                         irm.Check ( 0, 0, 0, 0, "irm" );
312                 }
313
314                 [Test]
315                 public void NestedTransactionScope9 ()
316                 {
317                         IntResourceManager irm = new IntResourceManager (1);
318                         IntResourceManager irm2 = new IntResourceManager (10);
319
320                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
321                         using (TransactionScope scope = new TransactionScope ()) {
322                                 irm.Value = 2;
323
324                                 using (TransactionScope scope2 = new TransactionScope (TransactionScopeOption.Suppress)) {
325                                         /* Not transactional, so this WONT get committed */
326                                         irm2.Value = 4;
327                                         scope2.Complete ();
328                                 }
329                                 irm2.Check ( 0, 0, 0, 0, "irm2" );
330
331                                 using (TransactionScope scope3 = new TransactionScope (TransactionScopeOption.RequiresNew)) {
332                                         irm.Value = 6;
333                                         scope3.Complete ();
334                                 }
335
336                                 /* vr's value has changed as the inner scope committed = 6 */
337                                 irm.Check ( 1, 1, 0, 0, "irm" );
338                                 Assert.AreEqual (irm.Value, 6, "#19");
339                                 Assert.AreEqual (irm.Actual, 6, "#20");
340                                 Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status, "#21");
341
342                                 scope.Complete ();
343                         }
344
345                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (after)");
346                         Assert.AreEqual (irm.Value, 6, "#22");
347                         irm.Check ( 2, 2, 0, 0, "irm" );
348                 }
349
350                 [Test]
351                 [ExpectedException (typeof (TransactionAbortedException))]
352                 public void NestedTransactionScope10 ()
353                 {
354                         IntResourceManager irm = new IntResourceManager (1);
355                         bool failed = false;
356
357                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
358                         using (TransactionScope scope = new TransactionScope ()) {
359                                 irm.Value = 2;
360
361                                 using (TransactionScope scope2 = new TransactionScope ()) {
362                                         irm.Value = 4;
363                                         /* Not completing this, so the transaction will
364                                          * get aborted 
365                                         scope2.Complete (); */
366                                 }
367
368                                 using (TransactionScope scope3 = new TransactionScope ()) {
369                                         /* Aborted transaction cannot be used for another
370                                          * TransactionScope 
371                                          */
372                                         //Assert.Fail ("Should not reach here.");
373                                         failed = true;
374                                 }
375                         }
376                         Assert.IsFalse ( failed, "Aborted Tx cannot be used for another TransactionScope" );
377                 }
378
379                 [Test]
380                 public void NestedTransactionScope12 ()
381                 {
382                         IntResourceManager irm = new IntResourceManager (1);
383
384                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
385                         using (TransactionScope scope = new TransactionScope ()) {
386                                 irm.Value = 2;
387
388                                 using (TransactionScope scope2 = new TransactionScope ()) {
389                                         irm.Value = 4;
390                                         /* Not completing this, so the transaction will
391                                          * get aborted 
392                                         scope2.Complete (); */
393                                 }
394
395                                 using (TransactionScope scope3 = new TransactionScope (TransactionScopeOption.RequiresNew)) {
396                                         /* Using RequiresNew here, so outer transaction
397                                          * being aborted doesn't matter
398                                          */
399                                         scope3.Complete (); 
400                                 }
401                         }
402                 }
403
404                 [Test]
405                 [ExpectedException (typeof (TransactionAbortedException))]
406                 public void NestedTransactionScope13 ()
407                 {
408                         IntResourceManager irm = new IntResourceManager ( 1 );
409
410                         Assert.IsNull ( Transaction.Current, "Ambient transaction exists (before)" );
411                         using ( TransactionScope scope = new TransactionScope () ) {
412                                 irm.Value = 2;
413
414                                 using ( TransactionScope scope2 = new TransactionScope () ) {
415                                         irm.Value = 4;
416                                         /* Not completing this, so the transaction will
417                                          * get aborted 
418                                         scope2.Complete (); */
419                                 }
420
421                                 scope.Complete ();
422                         }
423                 }
424                 #endregion
425
426                 /* Tests using IntResourceManager */
427
428                 [Test]
429                 public void RMFail1 ()
430                 {
431                         IntResourceManager irm = new IntResourceManager (1);
432                         IntResourceManager irm2 = new IntResourceManager (10);
433                         IntResourceManager irm3 = new IntResourceManager (12);
434
435                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
436                         try {
437                                 using (TransactionScope scope = new TransactionScope ()) {
438                                         irm.Value = 2;
439                                         irm2.Value = 20;
440                                         irm3.Value = 24;
441
442                                         /* Make second RM fail to prepare, this should throw
443                                          * TransactionAbortedException when the scope ends 
444                                          */
445                                         irm2.FailPrepare = true;
446                                         scope.Complete ();
447                                 }
448                         } catch (TransactionAbortedException) {
449                                 irm.Check ( 1, 0, 1, 0, "irm");
450                                 irm2.Check ( 1, 0, 0, 0, "irm2");
451                                 irm3.Check ( 0, 0, 1, 0, "irm3");
452                         }
453                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (after)");
454                 }
455
456                 [Test]
457                 [Category("NotWorking")]
458                 [Ignore("NotWorking")]
459                 public void RMFail2 ()
460                 {
461                         IntResourceManager irm = new IntResourceManager (1);
462                         IntResourceManager irm2 = new IntResourceManager (10);
463                         IntResourceManager irm3 = new IntResourceManager (12);
464
465                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
466                         try {
467                                 using (TransactionScope scope = new TransactionScope (TransactionScopeOption.Required, new TimeSpan (0, 0, 30))) {
468                                         irm.Value = 2;
469                                         irm2.Value = 20;
470                                         irm3.Value = 24;
471
472                                         /* irm2 wont call Prepared or ForceRollback in
473                                          * its Prepare (), so TransactionManager will timeout
474                                          * waiting for it 
475                                          */
476                                         irm2.IgnorePrepare = true;
477                                         scope.Complete ();
478                                 }
479                         } catch (TransactionAbortedException e) {
480                                 /* FIXME: Not working right now.. no timeout exception thrown! */
481                                 
482                                 Assert.IsNotNull ( e.InnerException, "innerexception is null" );
483                                 Assert.AreEqual (typeof (TimeoutException), e.InnerException.GetType (), "#32");
484
485                                 Assert.IsNull (Transaction.Current, "Ambient transaction exists (after)");
486                                 return;
487                         }
488
489                         Assert.Fail ("Expected TransactionAbortedException (TimeoutException)");
490                 }
491
492                 #region Explicit Transaction Tests
493
494                 [Test]
495                 public void ExplicitTransactionCommit ()
496                 {
497                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
498
499                         CommittableTransaction ct = new CommittableTransaction ();
500                         Transaction oldTransaction = Transaction.Current;
501                         Transaction.Current = ct;
502
503                         IntResourceManager irm = new IntResourceManager (1);
504                         irm.Value = 2;
505                         ct.Commit ();
506
507                         Assert.AreEqual (2, irm.Value, "#33");
508                         Assert.AreEqual (TransactionStatus.Committed, ct.TransactionInformation.Status, "#34");
509                         Transaction.Current = oldTransaction;
510                 }
511
512                 [Test]
513                 public void ExplicitTransactionRollback ()
514                 {
515                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
516
517                         CommittableTransaction ct = new CommittableTransaction ();
518                         Transaction oldTransaction = Transaction.Current;
519                         Transaction.Current = ct;
520
521                         IntResourceManager irm = new IntResourceManager (1);
522                         irm.Value = 2;
523                         Assert.AreEqual (TransactionStatus.Active, ct.TransactionInformation.Status, "#35");
524                         ct.Rollback ();
525
526                         Assert.AreEqual (1, irm.Value, "#36");
527                         Assert.AreEqual (TransactionStatus.Aborted, ct.TransactionInformation.Status, "#37");
528                         Transaction.Current = oldTransaction;
529                 }
530
531                 [Test]
532                 public void ExplicitTransaction1 ()
533                 {
534                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
535                         CommittableTransaction ct = new CommittableTransaction ();
536                         Transaction oldTransaction = Transaction.Current;
537
538                         Transaction.Current = ct;
539
540                         IntResourceManager irm = new IntResourceManager (1);
541
542                         irm.Value = 2;
543
544                         using (TransactionScope scope = new TransactionScope ()) {
545                                 Assert.AreEqual (ct, Transaction.Current, "#38");
546                                 irm.Value = 4;
547                                 scope.Complete ();
548                         }
549
550                         Assert.AreEqual (ct, Transaction.Current, "#39");
551                         Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status, "#40");
552                         Assert.AreEqual (1, irm.Actual, "#41"); /* Actual value */
553
554                         ct.Commit ();
555                         Assert.AreEqual (4, irm.Actual, "#42"); /* New committed actual value */
556                         Assert.AreEqual (TransactionStatus.Committed, Transaction.Current.TransactionInformation.Status, "#43");
557                         Transaction.Current = oldTransaction;
558                 }
559
560                 [Test]
561                 public void ExplicitTransaction2 ()
562                 {
563                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
564                         CommittableTransaction ct = new CommittableTransaction ();
565                         Transaction oldTransaction = Transaction.Current;
566
567                         Transaction.Current = ct;
568
569                         IntResourceManager irm = new IntResourceManager (1);
570
571                         irm.Value = 2;
572                         using (TransactionScope scope = new TransactionScope ()) {
573                                 Assert.AreEqual (ct, Transaction.Current, "#44");
574
575                                 /* Not calling scope.Complete
576                                 scope.Complete ();*/
577                         }
578
579                         Assert.AreEqual (TransactionStatus.Aborted, ct.TransactionInformation.Status, "#45");
580                         Assert.AreEqual (ct, Transaction.Current, "#46");
581                         Assert.AreEqual (1, irm.Actual, "#47");
582                         Assert.AreEqual (1, irm.NumRollback, "#48");
583                         irm.Check ( 0, 0, 1, 0, "irm" );
584                         Transaction.Current = oldTransaction;
585
586                         try {
587                                 ct.Commit ();
588                         } catch (TransactionAbortedException) {
589                                 return;
590                         }
591                         Assert.Fail ("Commit on an aborted transaction should fail");
592                 }
593
594                 [Test]
595                 public void ExplicitTransaction3 ()
596                 {
597                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
598                         CommittableTransaction ct = new CommittableTransaction ();
599                         Transaction oldTransaction = Transaction.Current;
600
601                         Transaction.Current = ct;
602
603                         IntResourceManager irm = new IntResourceManager (1);
604
605                         using (TransactionScope scope = new TransactionScope (TransactionScopeOption.RequiresNew)) {
606                                 Assert.IsTrue (ct != Transaction.Current, "Scope with RequiresNew should have a new ambient transaction");
607
608                                 irm.Value = 3;
609                                 scope.Complete ();
610                         }
611
612                         irm.Value = 2;
613
614                         Assert.AreEqual (3, irm.Actual, "#50");
615
616                         Assert.AreEqual (ct, Transaction.Current, "#51");
617                         ct.Commit ();
618                         Assert.AreEqual (2, irm.Actual, "#52");
619                         Transaction.Current = oldTransaction;
620                 }
621
622                 [Test]
623                 public void ExplicitTransaction4 ()
624                 {
625                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
626                         CommittableTransaction ct = new CommittableTransaction ();
627                         Transaction oldTransaction = Transaction.Current;
628
629                         /* Not setting ambient transaction 
630                          Transaction.Current = ct; 
631                          */
632
633                         IntResourceManager irm = new IntResourceManager (1);
634
635                         using (TransactionScope scope = new TransactionScope (ct)) {
636                                 Assert.AreEqual (ct, Transaction.Current, "#53");
637
638                                 irm.Value = 2;
639                                 scope.Complete ();
640                         }
641
642                         Assert.AreEqual (oldTransaction, Transaction.Current, "#54");
643                         Assert.AreEqual (TransactionStatus.Active, ct.TransactionInformation.Status, "#55");
644                         Assert.AreEqual (1, irm.Actual, "#56"); /* Actual value */
645
646                         ct.Commit ();
647                         Assert.AreEqual (2, irm.Actual, "#57"); /* New committed actual value */
648                         Assert.AreEqual (TransactionStatus.Committed, ct.TransactionInformation.Status, "#58");
649
650                         irm.Check ( 1, 1, 0, 0, "irm");
651                 }
652
653                 [Test]
654                 public void ExplicitTransaction5 ()
655                 {
656                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
657                         CommittableTransaction ct = new CommittableTransaction ();
658                         Transaction oldTransaction = Transaction.Current;
659
660                         /* Not setting ambient transaction 
661                          Transaction.Current = ct; 
662                          */
663
664                         IntResourceManager irm = new IntResourceManager (1);
665
666                         using (TransactionScope scope = new TransactionScope (ct)) {
667                                 Assert.AreEqual (ct, Transaction.Current, "#59");
668
669                                 irm.Value = 2;
670
671                                 /* Not completing this scope
672                                 scope.Complete (); */
673                         }
674
675                         Assert.AreEqual (oldTransaction, Transaction.Current, "#60");
676                         Assert.AreEqual (TransactionStatus.Aborted, ct.TransactionInformation.Status, "#61");
677                         Assert.AreEqual (1, irm.Actual, "#62"); /* Actual value */
678
679                         irm.Check ( 0, 0, 1, 0, "irm");
680                 }
681
682                 [Test]
683                 [ExpectedException (typeof (InvalidOperationException))]
684                 public void ExplicitTransaction6 ()
685                 {
686                         CommittableTransaction ct = new CommittableTransaction ();
687
688                         IntResourceManager irm = new IntResourceManager (1);
689                         irm.Value = 2;
690                         ct.Commit ();
691
692                         ct.Commit ();
693                 }
694
695                 [Test]
696                 [ExpectedException (typeof (InvalidOperationException))]
697                 public void ExplicitTransaction6a ()
698                 {
699                         CommittableTransaction ct = new CommittableTransaction ();
700
701                         IntResourceManager irm = new IntResourceManager ( 1 );
702                         irm.Value = 2;
703                         ct.Commit ();
704
705                         /* Using a already committed transaction in a new 
706                          * TransactionScope
707                          */
708                         TransactionScope scope = new TransactionScope ( ct );
709                 }
710
711                 [Test]
712                 public void ExplicitTransaction6b ()
713                 {
714                         CommittableTransaction ct = new CommittableTransaction ();
715
716                         IntResourceManager irm = new IntResourceManager ( 1 );
717                         
718                         Transaction.Current = ct; 
719
720                         TransactionScope scope1 = new TransactionScope ();
721                         /* Enlist */
722                         irm.Value = 2;
723
724                         scope1.Complete ();
725
726                         try {
727                                 ct.Commit ();
728                         } catch (TransactionAbortedException) {
729                                 irm.Check ( 0, 0, 1, 0, "irm" );
730                                 
731                                 scope1.Dispose ();
732                                 Transaction.Current = null;
733                                 return;
734                         }
735                         Assert.Fail ( "Commit should've failed" );
736                 }
737
738                 [Test]
739                 public void ExplicitTransaction6c ()
740                 {
741                         CommittableTransaction ct = new CommittableTransaction ();
742
743                         IntResourceManager irm = new IntResourceManager ( 1 );
744
745                         Transaction.Current = ct;
746
747                         TransactionScope scope1 = new TransactionScope (TransactionScopeOption.RequiresNew);
748                         /* Enlist */
749                         irm.Value = 2;
750
751                         TransactionScope scope2 = new TransactionScope ();
752                         try {
753                                 scope1.Dispose ();
754                         } catch (InvalidOperationException) {
755                                 /* Error: TransactionScope nested incorrectly */
756                                 irm.Check ( 0, 0, 1, 0, "irm" );
757                                 scope2.Dispose ();
758                                 Transaction.Current = null;
759                                 return;
760                         }
761
762                         Assert.Fail ("Commit should've failed");
763                 }
764
765                 [Test]
766                 public void ExplicitTransaction6d ()
767                 {
768                         CommittableTransaction ct = new CommittableTransaction ();
769
770                         IntResourceManager irm = new IntResourceManager ( 1 );
771
772                         Transaction.Current = ct;
773
774                         TransactionScope scope1 = new TransactionScope ();
775                         /* Enlist */
776                         irm.Value = 2;
777
778                         TransactionScope scope2 = new TransactionScope ( TransactionScopeOption.RequiresNew );
779                         try {
780                                 scope1.Dispose ();
781                         } catch (InvalidOperationException) {
782                                 /* Error: TransactionScope nested incorrectly */
783                                 scope2.Dispose ();
784                                 Transaction.Current = null;
785                                 return;
786                         }
787
788                         Assert.Fail ( "Commit should've failed" );
789                 }
790
791                 [Test]
792                 public void ExplicitTransaction6e ()
793                 {
794                         CommittableTransaction ct = new CommittableTransaction ();
795
796                         IntResourceManager irm = new IntResourceManager ( 1 );
797
798                         Transaction.Current = ct;
799
800                         TransactionScope scope1 = new TransactionScope ();
801                         /* Enlist */
802                         irm.Value = 2;
803
804                         TransactionScope scope2 = new TransactionScope ( TransactionScopeOption.Suppress);
805                         try {
806                                 scope1.Dispose ();
807                         } catch (InvalidOperationException) {
808                                 /* Error: TransactionScope nested incorrectly */
809                                 scope2.Dispose ();
810                                 Transaction.Current = null;
811                                 return;
812                         }
813
814                         Assert.Fail ( "Commit should've failed" );
815                 }
816
817                 [Test]
818                 [ExpectedException (typeof (TransactionException))]
819                 public void ExplicitTransaction7 ()
820                 {
821                         CommittableTransaction ct = new CommittableTransaction ();
822
823                         IntResourceManager irm = new IntResourceManager (1);
824                         irm.Value = 2;
825                         ct.Commit ();
826                         /* Cannot accept any new work now, so TransactionException */
827                         ct.Rollback ();
828                 }
829
830                 [Test]
831                 public void ExplicitTransaction8 ()
832                 {
833                         CommittableTransaction ct = new CommittableTransaction ();
834
835                         IntResourceManager irm = new IntResourceManager ( 1 );
836                         using ( TransactionScope scope = new TransactionScope (ct) ) {
837                                 irm.Value = 2;
838                                 /* FIXME: Why TransactionAbortedException ?? */
839                                 try {
840                                         ct.Commit ();
841                                 } catch ( TransactionAbortedException) {
842                                         irm.Check ( 0, 0, 1, 0, "irm" );
843                                         return;
844                                 }
845                                 Assert.Fail ( "Should not be reached" );
846                         }
847                 }
848
849                 [Test]
850                 public void ExplicitTransaction8a ()
851                 {
852                         CommittableTransaction ct = new CommittableTransaction ();
853
854                         IntResourceManager irm = new IntResourceManager ( 1 );
855                         using ( TransactionScope scope = new TransactionScope ( ct ) ) {
856                                 irm.Value = 2;
857                                 scope.Complete ();
858                                 /* FIXME: Why TransactionAbortedException ?? */
859                                 try {
860                                         ct.Commit ();
861                                 }
862                                 catch ( TransactionAbortedException) {
863                                         irm.Check ( 0, 0, 1, 0, "irm" );
864                                         return;
865                                 }
866                                 Assert.Fail ( "Should not be reached" );
867                         }
868                 }
869
870                 [Test]
871                 [ExpectedException (typeof (InvalidOperationException))]
872                 public void ExplicitTransaction9 ()
873                 {
874                         CommittableTransaction ct = new CommittableTransaction ();
875
876                         IntResourceManager irm = new IntResourceManager ( 1 );
877                         ct.BeginCommit ( null, null );
878                         ct.BeginCommit ( null, null );
879                 }
880
881                 [Test]
882                 public void ExplicitTransaction10 ()
883                 {
884                         CommittableTransaction ct = new CommittableTransaction ();
885
886                         IntResourceManager irm = new IntResourceManager ( 1 );
887                         Transaction.Current = ct;
888                         irm.Value = 2;
889
890                         TransactionScope scope = new TransactionScope ( ct );
891                         Assert.AreEqual ( ct, Transaction.Current, "ambient transaction" );
892                         //scope.Complete ();
893                         //scope.Dispose ();
894                         try {
895                                 ct.Commit ();
896                         } catch ( TransactionAbortedException) {
897                                 irm.Check ( 0, 0, 1, 0, "irm" );
898                                 Transaction.Current = null;
899                                 return;
900                         }
901                         
902                         Transaction.Current = null;
903                         Assert.Fail ("Expected TransactionAbortedException");
904                 }
905
906                 [Test]
907                 public void ExplicitTransaction10a ()
908                 {
909                         CommittableTransaction ct = new CommittableTransaction ();
910
911                         IntResourceManager irm = new IntResourceManager ( 1 );
912                         Transaction.Current = ct;
913                         irm.Value = 2;
914                         Transaction.Current = null;
915
916                         TransactionScope scope = new TransactionScope ( ct );
917                         Assert.AreEqual ( ct, Transaction.Current, "ambient transaction" );
918                         Transaction.Current = null;
919                         //scope2.Complete ();
920                         //scope2.Dispose ();
921                         try {
922                                 ct.Commit ();
923                         }
924                         catch ( TransactionAbortedException) {
925                                 irm.Check ( 0, 0, 1, 0, "irm" );
926                                 Transaction.Current = null;
927                                 return;
928                         }
929
930                         Transaction.Current = null;
931                         Assert.Fail ();
932                 }
933
934                 [Test]
935                 public void ExplicitTransaction10b ()
936                 {
937                         CommittableTransaction ct = new CommittableTransaction ();
938
939                         IntResourceManager irm = new IntResourceManager ( 1 );
940                         Transaction.Current = ct;
941                         irm.Value = 2;
942                         Transaction.Current = null;
943
944                         TransactionScope scope = new TransactionScope ( ct );
945                         Assert.AreEqual ( ct, Transaction.Current, "ambient transaction" );
946                         //scope2.Complete ();
947                         //scope2.Dispose ();
948                         IAsyncResult ar = ct.BeginCommit ( null, null );
949                         try {
950                                 ct.EndCommit (ar);
951                         }
952                         catch ( TransactionAbortedException) {
953                                 irm.Check ( 0, 0, 1, 0, "irm" );
954                                 Transaction.Current = null;
955                                 return;
956                         }
957
958                         Transaction.Current = null;
959                         Assert.Fail ();
960                 }
961
962                 [Test]
963                 [ExpectedException ( typeof (ArgumentException))]
964                 public void ExplicitTransaction12 ()
965                 {
966                         CommittableTransaction ct = new CommittableTransaction ();
967
968                         IntResourceManager irm = new IntResourceManager ( 1 );
969                         irm.FailPrepare = true;
970                         ct.BeginCommit ( null, null );
971                         ct.EndCommit ( null );
972                 }
973
974                 [Test]
975                 public void ExplicitTransaction13 ()
976                 {
977                         CommittableTransaction ct = new CommittableTransaction ();
978                         IntResourceManager irm = new IntResourceManager ( 1 );
979
980                         Assert.IsNull ( Transaction.Current );
981                         Transaction.Current = ct;
982                         irm.Value = 2;
983                         irm.FailPrepare = true;
984
985                         try {
986                                 ct.Commit ();
987                         } catch ( TransactionAbortedException ) {
988                                 Assert.AreEqual ( TransactionStatus.Aborted, ct.TransactionInformation.Status );
989                                 try {
990                                         ct.BeginCommit ( null, null );
991                                 } catch (Exception) {
992                                         Transaction.Current = null;
993                                         return;
994                                 }
995                                 Assert.Fail ( "Should not be reached(2)" );
996                         }
997                         Assert.Fail ("Should not be reached");
998                 }
999
1000                 [Test]
1001                 public void ExplicitTransaction14 ()
1002                 {
1003                         CommittableTransaction ct = new CommittableTransaction ();
1004                         IntResourceManager irm = new IntResourceManager ( 1 );
1005
1006                         Assert.IsNull ( Transaction.Current );
1007                         Transaction.Current = ct;
1008                         irm.Value = 2;
1009
1010                         ct.Commit ();
1011
1012                         Assert.AreEqual ( TransactionStatus.Committed, ct.TransactionInformation.Status );
1013                         try {
1014                                 ct.BeginCommit ( null, null );
1015                         }
1016                         catch ( Exception) {
1017                                 Transaction.Current = null;
1018                                 return;
1019                         }
1020                         Assert.Fail ( "Should not be reached" );
1021                 }
1022
1023                 [Test]
1024                 public void ExplicitTransaction15 ()
1025                 {
1026                         CommittableTransaction ct = new CommittableTransaction ();
1027                         IntResourceManager irm = new IntResourceManager ( 1 );
1028                         IntResourceManager irm2 = new IntResourceManager ( 3 );
1029
1030                         Assert.IsNull ( Transaction.Current );
1031                         Transaction.Current = ct;
1032
1033                         try {
1034                                 using (TransactionScope scope = new TransactionScope ()) {
1035                                         irm.Value = 2;
1036                                         Transaction.Current = new CommittableTransaction ();
1037                                         irm2.Value = 6;
1038                                 }
1039                         } catch (InvalidOperationException) {
1040                                 irm.Check ( 0, 0, 1, 0, "irm" );
1041                                 irm2.Check ( 0, 0, 1, 0, "irm2" );
1042                                 Transaction.Current = null;
1043                                 return;
1044                         }
1045
1046                         Assert.Fail ( "Should not be reached" );
1047                 }
1048
1049                 [Test]
1050                 public void ExplicitTransaction16 ()
1051                 {
1052                         CommittableTransaction ct = new CommittableTransaction ();
1053                         IntResourceManager irm0 = new IntResourceManager ( 3 );
1054                         IntResourceManager irm = new IntResourceManager ( 1 );
1055
1056                         Assert.IsNull ( Transaction.Current );
1057
1058                         Transaction.Current = ct;
1059
1060                         irm.FailPrepare = true;
1061                         irm.FailWithException = true;
1062                         irm.Value = 2;
1063                         irm0.Value = 6;
1064
1065                         try {
1066                                 ct.Commit ();
1067                         } catch (TransactionAbortedException e) {
1068                                 Assert.IsNotNull ( e.InnerException, "Expected an InnerException of type NotSupportedException" );
1069                                 Assert.AreEqual ( typeof (NotSupportedException), e.InnerException.GetType (), "Inner exception should be NotSupportedException" );
1070                                 irm.Check ( 1, 0, 0, 0, "irm" );
1071                                 irm0.Check ( 0, 0, 1, 0, "irm0" );
1072                                 Transaction.Current = null;
1073                                 return;
1074                         }
1075                          
1076                         Assert.Fail ( "Should not be reached" );
1077                 }
1078
1079                 #endregion
1080         }
1081
1082 }
1083