Merge branch 'master' of github.com:mono/mono into masterwork
[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                 public void RMFail2 ()
458                 {
459                         IntResourceManager irm = new IntResourceManager (1);
460                         IntResourceManager irm2 = new IntResourceManager (10);
461                         IntResourceManager irm3 = new IntResourceManager (12);
462
463                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
464                         try {
465                                 using (TransactionScope scope = new TransactionScope (TransactionScopeOption.Required, new TimeSpan (0, 0, 30))) {
466                                         irm.Value = 2;
467                                         irm2.Value = 20;
468                                         irm3.Value = 24;
469
470                                         /* irm2 wont call Prepared or ForceRollback in
471                                          * its Prepare (), so TransactionManager will timeout
472                                          * waiting for it 
473                                          */
474                                         irm2.IgnorePrepare = true;
475                                         scope.Complete ();
476                                 }
477                         } catch (TransactionAbortedException e) {
478                                 /* FIXME: Not working right now.. no timeout exception thrown! */
479                                 
480                                 Assert.IsNotNull ( e.InnerException, "innerexception is null" );
481                                 Assert.AreEqual (typeof (TimeoutException), e.InnerException.GetType (), "#32");
482
483                                 Assert.IsNull (Transaction.Current, "Ambient transaction exists (after)");
484                                 return;
485                         }
486
487                         Assert.Fail ("Expected TransactionAbortedException (TimeoutException)");
488                 }
489
490                 #region Explicit Transaction Tests
491
492                 [Test]
493                 public void ExplicitTransactionCommit ()
494                 {
495                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
496
497                         CommittableTransaction ct = new CommittableTransaction ();
498                         Transaction oldTransaction = Transaction.Current;
499                         Transaction.Current = ct;
500
501                         IntResourceManager irm = new IntResourceManager (1);
502                         irm.Value = 2;
503                         ct.Commit ();
504
505                         Assert.AreEqual (2, irm.Value, "#33");
506                         Assert.AreEqual (TransactionStatus.Committed, ct.TransactionInformation.Status, "#34");
507                         Transaction.Current = oldTransaction;
508                 }
509
510                 [Test]
511                 public void ExplicitTransactionRollback ()
512                 {
513                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
514
515                         CommittableTransaction ct = new CommittableTransaction ();
516                         Transaction oldTransaction = Transaction.Current;
517                         Transaction.Current = ct;
518
519                         IntResourceManager irm = new IntResourceManager (1);
520                         irm.Value = 2;
521                         Assert.AreEqual (TransactionStatus.Active, ct.TransactionInformation.Status, "#35");
522                         ct.Rollback ();
523
524                         Assert.AreEqual (1, irm.Value, "#36");
525                         Assert.AreEqual (TransactionStatus.Aborted, ct.TransactionInformation.Status, "#37");
526                         Transaction.Current = oldTransaction;
527                 }
528
529                 [Test]
530                 public void ExplicitTransaction1 ()
531                 {
532                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
533                         CommittableTransaction ct = new CommittableTransaction ();
534                         Transaction oldTransaction = Transaction.Current;
535
536                         Transaction.Current = ct;
537
538                         IntResourceManager irm = new IntResourceManager (1);
539
540                         irm.Value = 2;
541
542                         using (TransactionScope scope = new TransactionScope ()) {
543                                 Assert.AreEqual (ct, Transaction.Current, "#38");
544                                 irm.Value = 4;
545                                 scope.Complete ();
546                         }
547
548                         Assert.AreEqual (ct, Transaction.Current, "#39");
549                         Assert.AreEqual (TransactionStatus.Active, Transaction.Current.TransactionInformation.Status, "#40");
550                         Assert.AreEqual (1, irm.Actual, "#41"); /* Actual value */
551
552                         ct.Commit ();
553                         Assert.AreEqual (4, irm.Actual, "#42"); /* New committed actual value */
554                         Assert.AreEqual (TransactionStatus.Committed, Transaction.Current.TransactionInformation.Status, "#43");
555                         Transaction.Current = oldTransaction;
556                 }
557
558                 [Test]
559                 public void ExplicitTransaction2 ()
560                 {
561                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
562                         CommittableTransaction ct = new CommittableTransaction ();
563                         Transaction oldTransaction = Transaction.Current;
564
565                         Transaction.Current = ct;
566
567                         IntResourceManager irm = new IntResourceManager (1);
568
569                         irm.Value = 2;
570                         using (TransactionScope scope = new TransactionScope ()) {
571                                 Assert.AreEqual (ct, Transaction.Current, "#44");
572
573                                 /* Not calling scope.Complete
574                                 scope.Complete ();*/
575                         }
576
577                         Assert.AreEqual (TransactionStatus.Aborted, ct.TransactionInformation.Status, "#45");
578                         Assert.AreEqual (ct, Transaction.Current, "#46");
579                         Assert.AreEqual (1, irm.Actual, "#47");
580                         Assert.AreEqual (1, irm.NumRollback, "#48");
581                         irm.Check ( 0, 0, 1, 0, "irm" );
582                         Transaction.Current = oldTransaction;
583
584                         try {
585                                 ct.Commit ();
586                         } catch (TransactionAbortedException) {
587                                 return;
588                         }
589                         Assert.Fail ("Commit on an aborted transaction should fail");
590                 }
591
592                 [Test]
593                 public void ExplicitTransaction3 ()
594                 {
595                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
596                         CommittableTransaction ct = new CommittableTransaction ();
597                         Transaction oldTransaction = Transaction.Current;
598
599                         Transaction.Current = ct;
600
601                         IntResourceManager irm = new IntResourceManager (1);
602
603                         using (TransactionScope scope = new TransactionScope (TransactionScopeOption.RequiresNew)) {
604                                 Assert.IsTrue (ct != Transaction.Current, "Scope with RequiresNew should have a new ambient transaction");
605
606                                 irm.Value = 3;
607                                 scope.Complete ();
608                         }
609
610                         irm.Value = 2;
611
612                         Assert.AreEqual (3, irm.Actual, "#50");
613
614                         Assert.AreEqual (ct, Transaction.Current, "#51");
615                         ct.Commit ();
616                         Assert.AreEqual (2, irm.Actual, "#52");
617                         Transaction.Current = oldTransaction;
618                 }
619
620                 [Test]
621                 public void ExplicitTransaction4 ()
622                 {
623                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
624                         CommittableTransaction ct = new CommittableTransaction ();
625                         Transaction oldTransaction = Transaction.Current;
626
627                         /* Not setting ambient transaction 
628                          Transaction.Current = ct; 
629                          */
630
631                         IntResourceManager irm = new IntResourceManager (1);
632
633                         using (TransactionScope scope = new TransactionScope (ct)) {
634                                 Assert.AreEqual (ct, Transaction.Current, "#53");
635
636                                 irm.Value = 2;
637                                 scope.Complete ();
638                         }
639
640                         Assert.AreEqual (oldTransaction, Transaction.Current, "#54");
641                         Assert.AreEqual (TransactionStatus.Active, ct.TransactionInformation.Status, "#55");
642                         Assert.AreEqual (1, irm.Actual, "#56"); /* Actual value */
643
644                         ct.Commit ();
645                         Assert.AreEqual (2, irm.Actual, "#57"); /* New committed actual value */
646                         Assert.AreEqual (TransactionStatus.Committed, ct.TransactionInformation.Status, "#58");
647
648                         irm.Check ( 1, 1, 0, 0, "irm");
649                 }
650
651                 [Test]
652                 public void ExplicitTransaction5 ()
653                 {
654                         Assert.IsNull (Transaction.Current, "Ambient transaction exists (before)");
655                         CommittableTransaction ct = new CommittableTransaction ();
656                         Transaction oldTransaction = Transaction.Current;
657
658                         /* Not setting ambient transaction 
659                          Transaction.Current = ct; 
660                          */
661
662                         IntResourceManager irm = new IntResourceManager (1);
663
664                         using (TransactionScope scope = new TransactionScope (ct)) {
665                                 Assert.AreEqual (ct, Transaction.Current, "#59");
666
667                                 irm.Value = 2;
668
669                                 /* Not completing this scope
670                                 scope.Complete (); */
671                         }
672
673                         Assert.AreEqual (oldTransaction, Transaction.Current, "#60");
674                         Assert.AreEqual (TransactionStatus.Aborted, ct.TransactionInformation.Status, "#61");
675                         Assert.AreEqual (1, irm.Actual, "#62"); /* Actual value */
676
677                         irm.Check ( 0, 0, 1, 0, "irm");
678                 }
679
680                 [Test]
681                 [ExpectedException (typeof (InvalidOperationException))]
682                 public void ExplicitTransaction6 ()
683                 {
684                         CommittableTransaction ct = new CommittableTransaction ();
685
686                         IntResourceManager irm = new IntResourceManager (1);
687                         irm.Value = 2;
688                         ct.Commit ();
689
690                         ct.Commit ();
691                 }
692
693                 [Test]
694                 [ExpectedException (typeof (InvalidOperationException))]
695                 public void ExplicitTransaction6a ()
696                 {
697                         CommittableTransaction ct = new CommittableTransaction ();
698
699                         IntResourceManager irm = new IntResourceManager ( 1 );
700                         irm.Value = 2;
701                         ct.Commit ();
702
703                         /* Using a already committed transaction in a new 
704                          * TransactionScope
705                          */
706                         TransactionScope scope = new TransactionScope ( ct );
707                 }
708
709                 [Test]
710                 public void ExplicitTransaction6b ()
711                 {
712                         CommittableTransaction ct = new CommittableTransaction ();
713
714                         IntResourceManager irm = new IntResourceManager ( 1 );
715                         
716                         Transaction.Current = ct; 
717
718                         TransactionScope scope1 = new TransactionScope ();
719                         /* Enlist */
720                         irm.Value = 2;
721
722                         scope1.Complete ();
723
724                         try {
725                                 ct.Commit ();
726                         } catch (TransactionAbortedException) {
727                                 irm.Check ( 0, 0, 1, 0, "irm" );
728                                 
729                                 scope1.Dispose ();
730                                 Transaction.Current = null;
731                                 return;
732                         }
733                         Assert.Fail ( "Commit should've failed" );
734                 }
735
736                 [Test]
737                 public void ExplicitTransaction6c ()
738                 {
739                         CommittableTransaction ct = new CommittableTransaction ();
740
741                         IntResourceManager irm = new IntResourceManager ( 1 );
742
743                         Transaction.Current = ct;
744
745                         TransactionScope scope1 = new TransactionScope (TransactionScopeOption.RequiresNew);
746                         /* Enlist */
747                         irm.Value = 2;
748
749                         TransactionScope scope2 = new TransactionScope ();
750                         try {
751                                 scope1.Dispose ();
752                         } catch (InvalidOperationException) {
753                                 /* Error: TransactionScope nested incorrectly */
754                                 irm.Check ( 0, 0, 1, 0, "irm" );
755                                 scope2.Dispose ();
756                                 Transaction.Current = null;
757                                 return;
758                         }
759
760                         Assert.Fail ("Commit should've failed");
761                 }
762
763                 [Test]
764                 public void ExplicitTransaction6d ()
765                 {
766                         CommittableTransaction ct = new CommittableTransaction ();
767
768                         IntResourceManager irm = new IntResourceManager ( 1 );
769
770                         Transaction.Current = ct;
771
772                         TransactionScope scope1 = new TransactionScope ();
773                         /* Enlist */
774                         irm.Value = 2;
775
776                         TransactionScope scope2 = new TransactionScope ( TransactionScopeOption.RequiresNew );
777                         try {
778                                 scope1.Dispose ();
779                         } catch (InvalidOperationException) {
780                                 /* Error: TransactionScope nested incorrectly */
781                                 scope2.Dispose ();
782                                 Transaction.Current = null;
783                                 return;
784                         }
785
786                         Assert.Fail ( "Commit should've failed" );
787                 }
788
789                 [Test]
790                 public void ExplicitTransaction6e ()
791                 {
792                         CommittableTransaction ct = new CommittableTransaction ();
793
794                         IntResourceManager irm = new IntResourceManager ( 1 );
795
796                         Transaction.Current = ct;
797
798                         TransactionScope scope1 = new TransactionScope ();
799                         /* Enlist */
800                         irm.Value = 2;
801
802                         TransactionScope scope2 = new TransactionScope ( TransactionScopeOption.Suppress);
803                         try {
804                                 scope1.Dispose ();
805                         } catch (InvalidOperationException) {
806                                 /* Error: TransactionScope nested incorrectly */
807                                 scope2.Dispose ();
808                                 Transaction.Current = null;
809                                 return;
810                         }
811
812                         Assert.Fail ( "Commit should've failed" );
813                 }
814
815                 [Test]
816                 [ExpectedException (typeof (TransactionException))]
817                 public void ExplicitTransaction7 ()
818                 {
819                         CommittableTransaction ct = new CommittableTransaction ();
820
821                         IntResourceManager irm = new IntResourceManager (1);
822                         irm.Value = 2;
823                         ct.Commit ();
824                         /* Cannot accept any new work now, so TransactionException */
825                         ct.Rollback ();
826                 }
827
828                 [Test]
829                 public void ExplicitTransaction8 ()
830                 {
831                         CommittableTransaction ct = new CommittableTransaction ();
832
833                         IntResourceManager irm = new IntResourceManager ( 1 );
834                         using ( TransactionScope scope = new TransactionScope (ct) ) {
835                                 irm.Value = 2;
836                                 /* FIXME: Why TransactionAbortedException ?? */
837                                 try {
838                                         ct.Commit ();
839                                 } catch ( TransactionAbortedException) {
840                                         irm.Check ( 0, 0, 1, 0, "irm" );
841                                         return;
842                                 }
843                                 Assert.Fail ( "Should not be reached" );
844                         }
845                 }
846
847                 [Test]
848                 public void ExplicitTransaction8a ()
849                 {
850                         CommittableTransaction ct = new CommittableTransaction ();
851
852                         IntResourceManager irm = new IntResourceManager ( 1 );
853                         using ( TransactionScope scope = new TransactionScope ( ct ) ) {
854                                 irm.Value = 2;
855                                 scope.Complete ();
856                                 /* FIXME: Why TransactionAbortedException ?? */
857                                 try {
858                                         ct.Commit ();
859                                 }
860                                 catch ( TransactionAbortedException) {
861                                         irm.Check ( 0, 0, 1, 0, "irm" );
862                                         return;
863                                 }
864                                 Assert.Fail ( "Should not be reached" );
865                         }
866                 }
867
868                 [Test]
869                 [ExpectedException (typeof (InvalidOperationException))]
870                 public void ExplicitTransaction9 ()
871                 {
872                         CommittableTransaction ct = new CommittableTransaction ();
873
874                         IntResourceManager irm = new IntResourceManager ( 1 );
875                         ct.BeginCommit ( null, null );
876                         ct.BeginCommit ( null, null );
877                 }
878
879                 [Test]
880                 public void ExplicitTransaction10 ()
881                 {
882                         CommittableTransaction ct = new CommittableTransaction ();
883
884                         IntResourceManager irm = new IntResourceManager ( 1 );
885                         Transaction.Current = ct;
886                         irm.Value = 2;
887
888                         TransactionScope scope = new TransactionScope ( ct );
889                         Assert.AreEqual ( ct, Transaction.Current, "ambient transaction" );
890                         //scope.Complete ();
891                         //scope.Dispose ();
892                         try {
893                                 ct.Commit ();
894                         } catch ( TransactionAbortedException) {
895                                 irm.Check ( 0, 0, 1, 0, "irm" );
896                                 Transaction.Current = null;
897                                 return;
898                         }
899                         
900                         Transaction.Current = null;
901                         Assert.Fail ("Expected TransactionAbortedException");
902                 }
903
904                 [Test]
905                 public void ExplicitTransaction10a ()
906                 {
907                         CommittableTransaction ct = new CommittableTransaction ();
908
909                         IntResourceManager irm = new IntResourceManager ( 1 );
910                         Transaction.Current = ct;
911                         irm.Value = 2;
912                         Transaction.Current = null;
913
914                         TransactionScope scope = new TransactionScope ( ct );
915                         Assert.AreEqual ( ct, Transaction.Current, "ambient transaction" );
916                         Transaction.Current = null;
917                         //scope2.Complete ();
918                         //scope2.Dispose ();
919                         try {
920                                 ct.Commit ();
921                         }
922                         catch ( TransactionAbortedException) {
923                                 irm.Check ( 0, 0, 1, 0, "irm" );
924                                 Transaction.Current = null;
925                                 return;
926                         }
927
928                         Transaction.Current = null;
929                         Assert.Fail ();
930                 }
931
932                 [Test]
933                 public void ExplicitTransaction10b ()
934                 {
935                         CommittableTransaction ct = new CommittableTransaction ();
936
937                         IntResourceManager irm = new IntResourceManager ( 1 );
938                         Transaction.Current = ct;
939                         irm.Value = 2;
940                         Transaction.Current = null;
941
942                         TransactionScope scope = new TransactionScope ( ct );
943                         Assert.AreEqual ( ct, Transaction.Current, "ambient transaction" );
944                         //scope2.Complete ();
945                         //scope2.Dispose ();
946                         IAsyncResult ar = ct.BeginCommit ( null, null );
947                         try {
948                                 ct.EndCommit (ar);
949                         }
950                         catch ( TransactionAbortedException) {
951                                 irm.Check ( 0, 0, 1, 0, "irm" );
952                                 Transaction.Current = null;
953                                 return;
954                         }
955
956                         Transaction.Current = null;
957                         Assert.Fail ();
958                 }
959
960                 [Test]
961                 [ExpectedException ( typeof (ArgumentException))]
962                 public void ExplicitTransaction12 ()
963                 {
964                         CommittableTransaction ct = new CommittableTransaction ();
965
966                         IntResourceManager irm = new IntResourceManager ( 1 );
967                         irm.FailPrepare = true;
968                         ct.BeginCommit ( null, null );
969                         ct.EndCommit ( null );
970                 }
971
972                 [Test]
973                 public void ExplicitTransaction13 ()
974                 {
975                         CommittableTransaction ct = new CommittableTransaction ();
976                         IntResourceManager irm = new IntResourceManager ( 1 );
977
978                         Assert.IsNull ( Transaction.Current );
979                         Transaction.Current = ct;
980                         irm.Value = 2;
981                         irm.FailPrepare = true;
982
983                         try {
984                                 ct.Commit ();
985                         } catch ( TransactionAbortedException ) {
986                                 Assert.AreEqual ( TransactionStatus.Aborted, ct.TransactionInformation.Status );
987                                 try {
988                                         ct.BeginCommit ( null, null );
989                                 } catch (Exception) {
990                                         Transaction.Current = null;
991                                         return;
992                                 }
993                                 Assert.Fail ( "Should not be reached(2)" );
994                         }
995                         Assert.Fail ("Should not be reached");
996                 }
997
998                 [Test]
999                 public void ExplicitTransaction14 ()
1000                 {
1001                         CommittableTransaction ct = new CommittableTransaction ();
1002                         IntResourceManager irm = new IntResourceManager ( 1 );
1003
1004                         Assert.IsNull ( Transaction.Current );
1005                         Transaction.Current = ct;
1006                         irm.Value = 2;
1007
1008                         ct.Commit ();
1009
1010                         Assert.AreEqual ( TransactionStatus.Committed, ct.TransactionInformation.Status );
1011                         try {
1012                                 ct.BeginCommit ( null, null );
1013                         }
1014                         catch ( Exception) {
1015                                 Transaction.Current = null;
1016                                 return;
1017                         }
1018                         Assert.Fail ( "Should not be reached" );
1019                 }
1020
1021                 [Test]
1022                 public void ExplicitTransaction15 ()
1023                 {
1024                         CommittableTransaction ct = new CommittableTransaction ();
1025                         IntResourceManager irm = new IntResourceManager ( 1 );
1026                         IntResourceManager irm2 = new IntResourceManager ( 3 );
1027
1028                         Assert.IsNull ( Transaction.Current );
1029                         Transaction.Current = ct;
1030
1031                         try {
1032                                 using (TransactionScope scope = new TransactionScope ()) {
1033                                         irm.Value = 2;
1034                                         Transaction.Current = new CommittableTransaction ();
1035                                         irm2.Value = 6;
1036                                 }
1037                         } catch (InvalidOperationException) {
1038                                 irm.Check ( 0, 0, 1, 0, "irm" );
1039                                 irm2.Check ( 0, 0, 1, 0, "irm2" );
1040                                 Transaction.Current = null;
1041                                 return;
1042                         }
1043
1044                         Assert.Fail ( "Should not be reached" );
1045                 }
1046
1047                 [Test]
1048                 public void ExplicitTransaction16 ()
1049                 {
1050                         CommittableTransaction ct = new CommittableTransaction ();
1051                         IntResourceManager irm0 = new IntResourceManager ( 3 );
1052                         IntResourceManager irm = new IntResourceManager ( 1 );
1053
1054                         Assert.IsNull ( Transaction.Current );
1055
1056                         Transaction.Current = ct;
1057
1058                         irm.FailPrepare = true;
1059                         irm.FailWithException = true;
1060                         irm.Value = 2;
1061                         irm0.Value = 6;
1062
1063                         try {
1064                                 ct.Commit ();
1065                         } catch (TransactionAbortedException e) {
1066                                 Assert.IsNotNull ( e.InnerException, "Expected an InnerException of type NotSupportedException" );
1067                                 Assert.AreEqual ( typeof (NotSupportedException), e.InnerException.GetType (), "Inner exception should be NotSupportedException" );
1068                                 irm.Check ( 1, 0, 0, 0, "irm" );
1069                                 irm0.Check ( 0, 0, 1, 0, "irm0" );
1070                                 Transaction.Current = null;
1071                                 return;
1072                         }
1073                          
1074                         Assert.Fail ( "Should not be reached" );
1075                 }
1076
1077                 #endregion
1078         }
1079
1080 }
1081