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