* ThreadTest.cs: Removed tests for bug #81930, since other tests can
[mono.git] / mcs / class / corlib / Test / System.Threading / ThreadTest.cs
1 // ThreadTest.cs - NUnit Test Cases for the System.Threading.Thread class
2 //
3 // Authors
4 //      Eduardo Garcia Cebollero (kiwnix@yahoo.es)
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // (C) Eduardo Garcia Cebollero.
8 // (C) Ximian, Inc.  http://www.ximian.com
9 // (C) 2004 Novell (http://www.novell.com)
10 //
11
12 using System;
13 using System.Globalization;
14 using System.Security.Principal;
15 using System.Threading;
16
17 using NUnit.Framework;
18
19 namespace MonoTests.System.Threading
20 {
21         // These tests seem to hang the 2.0 framework. So they are disabled for now
22         // Don't reenable them until you can run a few thousand times on an SMP box.
23         [Category ("NotWorking")]
24         public class ThreadedPrincipalTest
25         {
26                 public static void NoPrincipal () 
27                 {
28 #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
29                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.NoPrincipal);
30 #endif
31                         IPrincipal p = Thread.CurrentPrincipal;
32                         Assert.IsNull (p, "#1");
33
34                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
35                         Assert.IsNotNull (Thread.CurrentPrincipal, "#2");
36
37                         Thread.CurrentPrincipal = null;
38                         Assert.IsNull (Thread.CurrentPrincipal, "#3");
39                         // in this case we can return to null
40                 }
41
42 #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
43                 public static void UnauthenticatedPrincipal () 
44                 {
45                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.UnauthenticatedPrincipal);
46                         IPrincipal p = Thread.CurrentPrincipal;
47                         Assert.IsNotNull (p, "#1");
48                         Assert.IsTrue ((p is GenericPrincipal), "#2");
49                         Assert.AreEqual (String.Empty, p.Identity.Name, "#3");
50                         Assert.AreEqual (String.Empty, p.Identity.AuthenticationType, "#4");
51                         Assert.IsFalse (p.Identity.IsAuthenticated, "#5");
52
53                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
54                         Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
55
56                         Thread.CurrentPrincipal = null;
57                         Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
58                         // in this case we can't return to null
59                 }
60
61                 public static void WindowsPrincipal () 
62                 {
63                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.WindowsPrincipal);
64                         IPrincipal p = Thread.CurrentPrincipal;
65                         Assert.IsNotNull (p, "#1");
66                         Assert.IsTrue ((p is WindowsPrincipal), "#2");
67                         Assert.IsNotNull (p.Identity.Name, "#3");
68                         Assert.IsNotNull (p.Identity.AuthenticationType, "#4");
69                         Assert.IsTrue (p.Identity.IsAuthenticated, "#5");
70
71                         // note: we can switch from a WindowsPrincipal to a GenericPrincipal
72                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
73                         Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
74
75                         Thread.CurrentPrincipal = null;
76                         Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
77                         // in this case we can't return to null
78                 }
79 #endif // TARGET_JVM
80
81                 public static void CopyOnNewThread ()
82                 {
83                         Assert.IsNotNull (Thread.CurrentPrincipal, "#1");
84                         Assert.AreEqual ("good", Thread.CurrentPrincipal.Identity.Name, "#2");
85                 }
86         }
87
88         [TestFixture]
89         [Category ("NotWorking")]
90         public class ThreadTest
91         {
92                 //Some Classes to test as threads
93                 private class C1Test
94                 {
95                         public int cnt;
96                         public Thread thread1;
97                         public bool endm1;
98                         public bool endm2;
99
100                         public C1Test()
101                         {
102                                 thread1 = (Thread)null;
103                                 this.cnt = 0;
104                                 endm1 = endm2 = false;
105                         }
106                         
107                         public void TestMethod()
108                         {
109                                 while (cnt < 10)
110                                 {
111                                         cnt++;
112                                 }
113                                 endm1 = true;
114                         }
115                         public void TestMethod2()
116                         {
117                                 if (!(thread1==(Thread)null) )
118                                 {
119                                         thread1.Join();
120                                 }
121                                 endm2 = true;
122                         }
123                 }
124
125                 private class C2Test
126                 {
127                         public int cnt;
128                         public bool run = false;
129                         
130                         public C2Test()
131                         {
132                                 this.cnt = 0;
133                         }
134
135                         public void TestMethod()
136                         {
137                                 run = true;
138                                 while (true)
139                                 {
140                                         if (cnt < 1000)
141                                                 cnt++;
142                                         else
143                                                 cnt = 0;
144                                 }
145                         }
146                 }
147                 
148                 private class C3Test
149                 {
150                         public C1Test sub_class;
151                         public Thread sub_thread;
152
153                         public C3Test()
154                         {
155                                 sub_class = new C1Test();
156                                 sub_thread = new Thread(new ThreadStart(sub_class.TestMethod));
157                         }
158
159                         public void TestMethod1()
160                         {
161                                 sub_thread.Start();
162                                 Thread.Sleep (100);
163                                 sub_thread.Abort();
164                         }
165                 }
166                 
167                 private class C4Test
168                 {
169                         public C1Test class1;
170                         public C1Test class2;
171                         public Thread thread1;
172                         public Thread thread2;
173                         public bool T1ON ;
174                         public bool T2ON ;
175
176                         public C4Test()
177                         {
178                                 T1ON = false;
179                                 T2ON = false;
180                                 class1 = new C1Test();
181                                 class2 = new C1Test();
182                                 thread1 = new Thread(new ThreadStart(class1.TestMethod));
183                                 thread2 = new Thread(new ThreadStart(class2.TestMethod));
184                         }
185
186                         public void TestMethod1()
187                         {
188                                 thread1.Start();
189                                 TestUtil.WaitForAlive (thread1, "wait1");
190                                 T1ON = true;
191                                 thread2.Start();
192                                 TestUtil.WaitForAlive (thread2, "wait2");
193                                 T2ON = true;
194                                 thread1.Abort();
195                                 TestUtil.WaitForNotAlive (thread1, "wait3");
196                                 T1ON = false;
197                                 thread2.Abort();
198                                 TestUtil.WaitForNotAlive (thread2, "wait4");
199                                 T2ON = false;
200                         }
201                         
202                         public void TestMethod2()
203                         {
204                                 thread1.Start();
205                                 thread1.Join();
206                         }
207                 }
208
209                 public void TestCtor1()
210                 {                       
211                         C1Test test1 = new C1Test();
212                         try
213                         {
214                                 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
215                         }
216                         catch (Exception e)
217                         {
218                                 Assert.Fail ("#01 Unexpected Exception Thrown: " + e.ToString ());
219                         }
220                 }
221
222                 [Category("NotDotNet")]
223                 public void TestStart()
224                 {
225                 {
226                         C1Test test1 = new C1Test();
227                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
228                         try
229                         {
230                                 TestThread.Start();
231                         }
232                         catch (Exception e)
233                         {
234                                 Assert.Fail ("#12 Unexpected Exception Thrown: " + e.ToString ());
235                         }
236                         TestThread.Join();
237                         Assert.AreEqual (10, test1.cnt, "#13 Thread Not started");
238                 }
239                 {
240                         bool errorThrown = false;
241                         C2Test test1 = new C2Test();
242                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
243                         TestThread.Start();
244                         TestThread.Abort();
245                         try
246                         {
247                                 TestThread.Start();
248                         }
249                         catch(ThreadStateException)
250                         {
251                                 errorThrown = true;
252                         }
253                         Assert.IsTrue (errorThrown, "#14 no ThreadStateException trown");
254                 }
255                 {
256                         C2Test test1 = new C2Test();
257                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
258                         TestThread.Start();
259                         while(!test1.run);
260                         bool started = (TestThread.ThreadState == ThreadState.Running);
261                         Assert.AreEqual (started, test1.run, "#15 Thread Is not in the correct state: ");
262                         TestThread.Abort();
263                 }
264                 }
265
266                 public void TestApartment()
267                 {
268                         C2Test test1 = new C2Test();
269                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
270                         ApartmentState before = TestThread.ApartmentState;
271                         TestThread.Start();
272                         TestUtil.WaitForAlive (TestThread, "wait5");
273                         ApartmentState after = TestThread.ApartmentState;
274                         TestThread.Abort();
275                         Assert.AreEqual (before, after, "#21 Apartment State Changed when not needed");
276                 }
277
278                 [Category("NotDotNet")]
279                 public void TestApartmentState()
280                 {
281                         C2Test test1 = new C2Test();
282                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
283                         ApartmentState before = TestThread.ApartmentState;
284                         TestThread.Start();
285                         TestUtil.WaitForAlive (TestThread, "wait6");
286                         ApartmentState after = TestThread.ApartmentState;
287                         TestThread.Abort();
288                         Assert.AreEqual (before, after, "#31 Apartment State Changed when not needed: ");
289                 }
290
291                 public void TestPriority1()
292                 {
293                         C2Test test1 = new C2Test();
294                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
295                         try {
296                                 TestThread.Priority=ThreadPriority.BelowNormal;
297                                 ThreadPriority after = TestThread.Priority;
298                                 TestThread.Start();
299                                 TestUtil.WaitForAlive (TestThread, "wait7");
300                                 ThreadPriority before = TestThread.Priority;
301                                 Assert.AreEqual (before, after, "#41 Unexpected Priority Change: ");
302                         }
303                         finally {
304                                 TestThread.Abort();
305                         }
306                 }
307
308                 [Test]
309                 public void AbortUnstarted ()
310                 {
311                         C2Test test1 = new C2Test();
312                         Thread th = new Thread (new ThreadStart (test1.TestMethod));
313                         th.Abort ();
314                         th.Start ();
315                 }
316
317                 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
318                 public void TestPriority2()
319                 {
320                         C2Test test1 = new C2Test();
321                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
322                         try {
323                                 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#42 Incorrect Priority in New thread: ");
324                                 TestThread.Start();
325                                 TestUtil.WaitForAliveOrStop (TestThread, "wait8");
326                                 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#43 Incorrect Priority in Started thread: ");
327                         }
328                         finally {
329                                 TestThread.Abort();
330                         }
331                         Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#44 Incorrect Priority in Aborted thread: ");
332                 }
333
334                 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
335                 public void TestPriority3()
336                 {
337                         C2Test test1 = new C2Test();
338                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
339                         try {
340                                 TestThread.Start();
341                                 TestThread.Priority = ThreadPriority.Lowest;
342                                 Assert.AreEqual (ThreadPriority.Lowest, TestThread.Priority, "#45A Incorrect Priority:");
343                                 TestThread.Priority = ThreadPriority.BelowNormal;
344                                 Assert.AreEqual (ThreadPriority.BelowNormal, TestThread.Priority, "#45B Incorrect Priority:");
345                                 TestThread.Priority = ThreadPriority.Normal;
346                                 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#45C Incorrect Priority:");
347                                 TestThread.Priority = ThreadPriority.AboveNormal;
348                                 Assert.AreEqual (ThreadPriority.AboveNormal, TestThread.Priority, "#45D Incorrect Priority:");
349                                 TestThread.Priority = ThreadPriority.Highest;
350                                 Assert.AreEqual (ThreadPriority.Highest, TestThread.Priority, "#45E Incorrect Priority:");
351                         }
352                         finally {
353                                 TestThread.Abort();
354                         }
355                 }
356
357                 public void TestIsBackground1()
358                 {
359                         C2Test test1 = new C2Test();
360                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
361                         try {
362                                 TestThread.Start();
363                                 TestUtil.WaitForAlive (TestThread, "wait9");
364                                 bool state = TestThread.IsBackground;
365                                 Assert.IsFalse (state, "#51 IsBackground not set at the default state: ");
366                         }
367                         finally {
368                                 TestThread.Abort();
369                         }
370                 }
371
372                 public void TestIsBackground2()
373                 {
374                         C2Test test1 = new C2Test();
375                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
376                         TestThread.IsBackground = true;
377                         try {
378                                 TestThread.Start();
379                         }
380                         finally {
381                                 TestThread.Abort();
382                         }
383                         Assert.IsTrue (TestThread.IsBackground, "#52 Is Background Changed ot Start ");
384                 }
385
386
387                 public void TestName()
388                 {
389                         C2Test test1 = new C2Test();
390                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
391                         try {
392                                 TestThread.Start();
393                                 TestUtil.WaitForAlive (TestThread, "wait10");
394                                 string name = TestThread.Name;
395                                 Assert.IsNull (name, "#61 Name set when mustn't be set: ");
396                                 string newname = "Testing....";
397                                 TestThread.Name = newname;
398                                 Assert.AreEqual (newname, TestThread.Name, "#62 Name not set when must be set: ");
399                         }
400                         finally {
401                                 TestThread.Abort();
402                         }
403                 }
404
405                 [Category("NotDotNet")]
406                 public void TestNestedThreads1()
407                 {
408                         C3Test  test1 = new C3Test();
409                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
410                         try {
411                                 TestThread.Start();
412                                 TestUtil.WaitForAlive (TestThread, "wait11");
413                         }
414                         catch(Exception e) {
415                                 Assert.Fail ("#71 Unexpected Exception" + e.Message);
416                         }
417                         finally {
418                                 TestThread.Abort();
419                         }
420                 }
421
422                 public void TestNestedThreads2()
423                 {
424                         C4Test test1 = new C4Test();
425                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
426                         try {
427                                 TestThread.Start();
428                         }
429                         catch(Exception e) {
430                                 Assert.Fail ("#81 Unexpected Exception" + e.ToString());
431                         }
432                         finally {
433                                 TestThread.Abort();
434                         }
435                 }
436
437                 
438                 public void TestJoin1()
439                 {
440                         C1Test test1 = new C1Test();
441                         C1Test test2 = new C1Test();
442                         Thread thread1 = new Thread(new ThreadStart(test1.TestMethod));
443                         Thread thread2 = new Thread(new ThreadStart(test1.TestMethod2));
444                         try
445                         {
446                                 thread1.Start();
447                                 thread2.Start();
448                                 thread2.Join();
449                         }
450                         catch(Exception e)
451                         {
452                                 Assert.Fail ("#91 Unexpected Exception " + e.ToString());
453                         }
454                         finally
455                         {
456                                 thread1.Abort();
457                                 thread2.Abort();
458                         }
459                 }
460                 
461                 public void TestThreadState()
462                 {
463                         //TODO: Test The rest of the possible transitions
464                         C2Test test1 = new C2Test();
465                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
466                         Assert.AreEqual (ThreadState.Unstarted, TestThread.ThreadState, "#101 Wrong Thread State");
467                         try {
468                                 TestThread.Start();
469                                 //while(!TestThread.IsAlive); //In the MS Documentation this is not necessary
470                                                                                           //but in the MS SDK it is
471                                 Assert.IsTrue (TestThread.ThreadState == ThreadState.Running || (TestThread.ThreadState & ThreadState.Unstarted) != 0,
472                                         "#102 Wrong Thread State: " + TestThread.ThreadState.ToString ());
473                         }
474                         finally {
475                                 TestThread.Abort();
476                         }
477                         
478                         TestUtil.WaitForNotAlive (TestThread, "wait12");
479                         // Docs say state will be Stopped, but Aborted happens sometimes (?)
480                         Assert.IsTrue ((ThreadState.Stopped & TestThread.ThreadState) != 0 || (ThreadState.Aborted & TestThread.ThreadState) != 0,
481                                 "#103 Wrong Thread State: " + TestThread.ThreadState.ToString ());
482                 } 
483
484                 [Test]
485                 [Ignore ("see comment below.")]
486                 public void CurrentPrincipal_PrincipalPolicy_NoPrincipal () 
487                 {
488                         // note: switching from PrincipalPolicy won't work inside the same thread
489                         // because as soon as a Principal object is created the Policy doesn't matter anymore
490                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.NoPrincipal));
491                         try {
492                                 t.Start ();
493                                 t.Join ();
494                         }
495                         catch {
496                                 t.Abort ();
497                         }
498                 }
499
500 #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
501                 [Test]
502                 [Ignore ("see comment below.")]
503                 public void CurrentPrincipal_PrincipalPolicy_UnauthenticatedPrincipal () 
504                 {
505                         // note: switching from PrincipalPolicy won't work inside the same thread
506                         // because as soon as a Principal object is created the Policy doesn't matter anymore
507                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.UnauthenticatedPrincipal));
508                         try {
509                                 t.Start ();
510                                 t.Join ();
511                         }
512                         catch {
513                                 t.Abort ();
514                         }
515                 }
516
517                 [Test]
518                 public void CurrentPrincipal_PrincipalPolicy_WindowsPrincipal () 
519                 {
520                         // note: switching from PrincipalPolicy won't work inside the same thread
521                         // because as soon as a Principal object is created the Policy doesn't matter anymore
522                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.WindowsPrincipal));
523                         try {
524                                 t.Start ();
525                                 t.Join ();
526                         }
527                         catch {
528                                 t.Abort ();
529                         }
530                 }
531 #endif // TARGET_JVM
532                 
533                 [Test]
534                 public void IPrincipal_CopyOnNewThread () 
535                 {
536                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("bad"), null);
537                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.CopyOnNewThread));
538                         try {
539                                 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("good"), null);
540                                 t.Start ();
541                                 t.Join ();
542                         }
543                         catch {
544                                 t.Abort ();
545                         }
546                 }
547
548                 int counter = 0;
549                 
550                 [Category("NotDotNet")]
551                 public void TestSuspend ()
552                 {
553                         Thread t = new Thread (new ThreadStart (DoCount));
554                         t.IsBackground = true;
555                         t.Start ();
556                         
557                         CheckIsRunning ("t1", t);
558                         
559                         t.Suspend ();
560                         WaitSuspended ("t2", t);
561                         
562                         CheckIsNotRunning ("t3", t);
563                         
564                         t.Resume ();
565                         WaitResumed ("t4", t);
566                         
567                         CheckIsRunning ("t5", t);
568                         
569                         t.Abort ();
570                         TestUtil.WaitForNotAlive (t, "wait13");
571                         CheckIsNotRunning ("t6", t);
572                 }
573                 
574                 [Category("NotDotNet")]
575                 [Category("NotWorking")]
576                 public void TestSuspendAbort ()
577                 {
578                         Thread t = new Thread (new ThreadStart (DoCount));
579                         t.IsBackground = true;
580                         t.Start ();
581                         
582                         CheckIsRunning ("t1", t);
583                         
584                         t.Suspend ();
585                         WaitSuspended ("t2", t);
586                         
587                         CheckIsNotRunning ("t3", t);
588                         
589                         t.Abort ();
590                         
591                         int n=0;
592                         while (t.IsAlive && n < 200) {
593                                 Thread.Sleep (10);
594                                 n++;
595                         }
596
597                         Assert.IsTrue (n < 200, "Timeout while waiting for abort");
598                         
599                         CheckIsNotRunning ("t6", t);
600                 }
601                 
602                 void CheckIsRunning (string s, Thread t)
603                 {
604                         int c = counter;
605                         Thread.Sleep (100);
606                         Assert.IsTrue (counter > c, s);
607                 }
608                 
609                 void CheckIsNotRunning (string s, Thread t)
610                 {
611                         int c = counter;
612                         Thread.Sleep (100);
613                         Assert.AreEqual (counter, c, s);
614                 }
615                 
616                 void WaitSuspended (string s, Thread t)
617                 {
618                         int n=0;
619                         ThreadState state = t.ThreadState;
620                         while ((state & ThreadState.Suspended) == 0) {
621                                 Assert.IsTrue ((state & ThreadState.SuspendRequested) != 0, s + ": expected SuspendRequested state");
622                                 Thread.Sleep (10);
623                                 n++;
624                                 Assert.IsTrue (n < 100, s + ": failed to suspend");
625                                 state = t.ThreadState;
626                         }
627                         Assert.IsTrue ((state & ThreadState.SuspendRequested) == 0, s + ": SuspendRequested state not expected");
628                 }
629                 
630                 void WaitResumed (string s, Thread t)
631                 {
632                         int n=0;
633                         while ((t.ThreadState & ThreadState.Suspended) != 0) {
634                                 Thread.Sleep (10);
635                                 n++;
636                                 Assert.IsTrue (n < 100, s + ": failed to resume");
637                         }
638                 }
639                 
640                 public void DoCount ()
641                 {
642                         while (true) {
643                                 counter++;
644                                 Thread.Sleep (1);
645                         }
646                 }
647         }
648
649         [TestFixture]
650         public class ThreadStateTest {
651                 void Start ()
652                 {
653                 }
654
655                 [Test] // bug #81720
656                 public void IsBackGround ()
657                 {
658                         Thread t1 = new Thread (new ThreadStart (Start));
659                         Assert.AreEqual (ThreadState.Unstarted, t1.ThreadState, "#A1");
660                         Assert.IsFalse (t1.IsBackground, "#A2");
661                         t1.Start ();
662                         t1.Join ();
663                         Assert.AreEqual (ThreadState.Stopped, t1.ThreadState, "#A3");
664
665                         // uncomment when bug #81658 is fixed
666                         /*
667                         try {
668                                 bool isBackGround = t1.IsBackground;
669                                 Assert.Fail ("#A4: " + isBackGround.ToString ());
670                         } catch (ThreadStateException ex) {
671                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A5");
672                                 Assert.IsNull (ex.InnerException, "#A6");
673                                 Assert.IsNotNull (ex.Message, "#A7");
674                         }
675                         */
676
677                         Thread t2 = new Thread (new ThreadStart (Start));
678                         Assert.AreEqual (ThreadState.Unstarted, t2.ThreadState, "#B1");
679                         t2.IsBackground = true;
680                         Assert.AreEqual (ThreadState.Unstarted | ThreadState.Background, t2.ThreadState, "#B2");
681                         Assert.IsTrue (t2.IsBackground, "#B3");
682                         t2.Start ();
683                         t2.Join ();
684                         Assert.AreEqual (ThreadState.Stopped, t2.ThreadState, "#B4");
685                         // uncomment when bug #81658 is fixed
686                         /*
687                         try {
688                                 bool isBackGround = t2.IsBackground;
689                                 Assert.Fail ("#B5: " + isBackGround.ToString ());
690                         } catch (ThreadStateException ex) {
691                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B6");
692                                 Assert.IsNull (ex.InnerException, "#B7");
693                                 Assert.IsNotNull (ex.Message, "#B8");
694                         }
695                         */
696                 }
697         }
698
699         [TestFixture]
700         public class ThreadApartmentTest
701         {
702                 void Start ()
703                 {
704                 }
705
706                 [Test] // bug #81658
707                 [Category ("NotWorking")]
708                 public void ApartmentState_StoppedThread ()
709                 {
710                         Thread t1 = new Thread (new ThreadStart (Start));
711                         t1.Start ();
712                         t1.Join ();
713                         try {
714                                 ApartmentState state = t1.ApartmentState;
715                                 Assert.Fail ("#A1: " + state.ToString ());
716                         } catch (ThreadStateException ex) {
717                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A2");
718                                 Assert.IsNull (ex.InnerException, "#A3");
719                                 Assert.IsNotNull (ex.Message, "#A4");
720                         }
721
722                         Thread t2 = new Thread (new ThreadStart (Start));
723                         t2.IsBackground = true;
724                         t2.Start ();
725                         t2.Join ();
726                         try {
727                                 ApartmentState state = t2.ApartmentState;
728                                 Assert.Fail ("#B1: " + state.ToString ());
729                         } catch (ThreadStateException ex) {
730                                 Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B2");
731                                 Assert.IsNull (ex.InnerException, "#B3");
732                                 Assert.IsNotNull (ex.Message, "#B4");
733                         }
734                 }
735
736                 [Test]
737                 public void ApartmentState_BackGround ()
738                 {
739                         Thread t1 = new Thread (new ThreadStart (Start));
740                         t1.IsBackground = true;
741                         Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "#1");
742                         t1.ApartmentState = ApartmentState.STA;
743                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#2");
744                 }
745
746                 [Test]
747                 public void TestApartmentState ()
748                 {
749                         Thread t1 = new Thread (new ThreadStart (Start));
750                         Thread t2 = new Thread (new ThreadStart (Start));
751                         Thread t3 = new Thread (new ThreadStart (Start));
752
753                         Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "Thread1 Default");
754                         Assert.AreEqual (ApartmentState.Unknown, t2.ApartmentState, "Thread2 Default");
755                         Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Default");
756
757                         t1.ApartmentState = ApartmentState.STA;
758                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
759                         t1.ApartmentState = ApartmentState.MTA;
760                         Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Twice");
761
762                         t2.ApartmentState = ApartmentState.MTA;
763                         Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Once");
764                         t2.ApartmentState = ApartmentState.STA;
765                         Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Twice");
766
767                         bool exception_occured = false;
768                         try {
769                                 t3.ApartmentState = ApartmentState.Unknown;
770                         }
771                         catch (Exception) {
772                                 exception_occured = true;
773                         }
774                         Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Set Invalid");
775 #if NET_2_0
776                         Assert.IsFalse (exception_occured, "Thread3 Set Invalid Exception Occured");
777 #else
778                         Assert.IsTrue (exception_occured, "Thread3 Set Invalid Exception Occured");
779 #endif
780
781                         t1.Start ();
782                         exception_occured = false;
783                         try {
784                                 t1.ApartmentState = ApartmentState.STA;
785                         }
786                         catch (Exception) {
787                                 exception_occured = true;
788                         }
789                         Assert.IsTrue (exception_occured, "Thread1 Started Invalid Exception Occured");
790                 }
791         }
792
793         public class TestUtil
794         {
795                 public static void WaitForNotAlive (Thread t, string s)
796                 {
797                         WhileAlive (t, true, s);
798                 }
799                 
800                 public static void WaitForAlive (Thread t, string s)
801                 {
802                         WhileAlive (t, false, s);
803                 }
804                 
805                 public static bool WaitForAliveOrStop (Thread t, string s)
806                 {
807                         return WhileAliveOrStop (t, false, s);
808                 }
809                 
810                 public static void WhileAlive (Thread t, bool alive, string s)
811                 {
812                         DateTime ti = DateTime.Now;
813                         while (t.IsAlive == alive) {
814                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
815                                         if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
816                                         else Assert.Fail ("Timeout while waiting for alive state. " + s);
817                                 }
818                         }
819                 }
820
821                 public static bool WhileAliveOrStop (Thread t, bool alive, string s)
822                 {
823                         DateTime ti = DateTime.Now;
824                         while (t.IsAlive == alive) {
825                                 if (t.ThreadState == ThreadState.Stopped)
826                                         return false;
827
828                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
829                                         if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
830                                         else Assert.Fail ("Timeout while waiting for alive state. " + s);
831                                 }
832                         }
833
834                         return true;
835                 }
836         }
837 }