1 // ThreadTest.cs - NUnit Test Cases for the System.Threading.Thread class
4 // Eduardo Garcia Cebollero (kiwnix@yahoo.es)
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) Eduardo Garcia Cebollero.
8 // (C) Ximian, Inc. http://www.ximian.com
9 // (C) 2004 Novell (http://www.novell.com)
13 using System.Globalization;
14 using System.Security.Principal;
15 using System.Threading;
17 using NUnit.Framework;
19 namespace MonoTests.System.Threading
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
26 public static void NoPrincipal ()
28 #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
29 AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.NoPrincipal);
31 IPrincipal p = Thread.CurrentPrincipal;
32 Assert.IsNull (p, "#1");
34 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
35 Assert.IsNotNull (Thread.CurrentPrincipal, "#2");
37 Thread.CurrentPrincipal = null;
38 Assert.IsNull (Thread.CurrentPrincipal, "#3");
39 // in this case we can return to null
42 #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
43 public static void UnauthenticatedPrincipal ()
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");
53 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
54 Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
56 Thread.CurrentPrincipal = null;
57 Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
58 // in this case we can't return to null
61 public static void WindowsPrincipal ()
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");
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");
75 Thread.CurrentPrincipal = null;
76 Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
77 // in this case we can't return to null
81 public static void CopyOnNewThread ()
83 Assert.IsNotNull (Thread.CurrentPrincipal, "#1");
84 Assert.AreEqual ("good", Thread.CurrentPrincipal.Identity.Name, "#2");
89 [Category ("NotWorking")]
90 public class ThreadTest
92 //Some Classes to test as threads
96 public Thread thread1;
102 thread1 = (Thread)null;
104 endm1 = endm2 = false;
107 public void TestMethod()
115 public void TestMethod2()
117 if (!(thread1==(Thread)null) )
128 public bool run = false;
135 public void TestMethod()
150 public C1Test sub_class;
151 public Thread sub_thread;
155 sub_class = new C1Test();
156 sub_thread = new Thread(new ThreadStart(sub_class.TestMethod));
159 public void TestMethod1()
169 public C1Test class1;
170 public C1Test class2;
171 public Thread thread1;
172 public Thread thread2;
180 class1 = new C1Test();
181 class2 = new C1Test();
182 thread1 = new Thread(new ThreadStart(class1.TestMethod));
183 thread2 = new Thread(new ThreadStart(class2.TestMethod));
186 public void TestMethod1()
189 TestUtil.WaitForAlive (thread1, "wait1");
192 TestUtil.WaitForAlive (thread2, "wait2");
195 TestUtil.WaitForNotAlive (thread1, "wait3");
198 TestUtil.WaitForNotAlive (thread2, "wait4");
202 public void TestMethod2()
209 public void TestCtor1()
211 C1Test test1 = new C1Test();
214 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
218 Assert.Fail ("#01 Unexpected Exception Thrown: " + e.ToString ());
222 [Category("NotDotNet")]
223 public void TestStart()
226 C1Test test1 = new C1Test();
227 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
234 Assert.Fail ("#12 Unexpected Exception Thrown: " + e.ToString ());
237 Assert.AreEqual (10, test1.cnt, "#13 Thread Not started");
240 bool errorThrown = false;
241 C2Test test1 = new C2Test();
242 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
249 catch(ThreadStateException)
253 Assert.IsTrue (errorThrown, "#14 no ThreadStateException trown");
256 C2Test test1 = new C2Test();
257 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
260 bool started = (TestThread.ThreadState == ThreadState.Running);
261 Assert.AreEqual (started, test1.run, "#15 Thread Is not in the correct state: ");
266 public void TestApartment()
268 C2Test test1 = new C2Test();
269 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
270 ApartmentState before = TestThread.ApartmentState;
272 TestUtil.WaitForAlive (TestThread, "wait5");
273 ApartmentState after = TestThread.ApartmentState;
275 Assert.AreEqual (before, after, "#21 Apartment State Changed when not needed");
278 [Category("NotDotNet")]
279 public void TestApartmentState()
281 C2Test test1 = new C2Test();
282 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
283 ApartmentState before = TestThread.ApartmentState;
285 TestUtil.WaitForAlive (TestThread, "wait6");
286 ApartmentState after = TestThread.ApartmentState;
288 Assert.AreEqual (before, after, "#31 Apartment State Changed when not needed: ");
291 public void TestPriority1()
293 C2Test test1 = new C2Test();
294 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
296 TestThread.Priority=ThreadPriority.BelowNormal;
297 ThreadPriority after = TestThread.Priority;
299 TestUtil.WaitForAlive (TestThread, "wait7");
300 ThreadPriority before = TestThread.Priority;
301 Assert.AreEqual (before, after, "#41 Unexpected Priority Change: ");
309 public void AbortUnstarted ()
311 C2Test test1 = new C2Test();
312 Thread th = new Thread (new ThreadStart (test1.TestMethod));
317 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
318 public void TestPriority2()
320 C2Test test1 = new C2Test();
321 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
323 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#42 Incorrect Priority in New thread: ");
325 TestUtil.WaitForAliveOrStop (TestThread, "wait8");
326 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#43 Incorrect Priority in Started thread: ");
331 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#44 Incorrect Priority in Aborted thread: ");
334 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
335 public void TestPriority3()
337 C2Test test1 = new C2Test();
338 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
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:");
357 public void TestIsBackground1()
359 C2Test test1 = new C2Test();
360 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
363 TestUtil.WaitForAlive (TestThread, "wait9");
364 bool state = TestThread.IsBackground;
365 Assert.IsFalse (state, "#51 IsBackground not set at the default state: ");
372 public void TestIsBackground2()
374 C2Test test1 = new C2Test();
375 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
376 TestThread.IsBackground = true;
383 Assert.IsTrue (TestThread.IsBackground, "#52 Is Background Changed ot Start ");
387 public void TestName()
389 C2Test test1 = new C2Test();
390 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
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: ");
405 [Category("NotDotNet")]
406 public void TestNestedThreads1()
408 C3Test test1 = new C3Test();
409 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
412 TestUtil.WaitForAlive (TestThread, "wait11");
415 Assert.Fail ("#71 Unexpected Exception" + e.Message);
422 public void TestNestedThreads2()
424 C4Test test1 = new C4Test();
425 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
430 Assert.Fail ("#81 Unexpected Exception" + e.ToString());
438 public void TestJoin1()
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));
452 Assert.Fail ("#91 Unexpected Exception " + e.ToString());
461 public void TestThreadState()
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");
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 ());
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 ());
485 [Ignore ("see comment below.")]
486 public void CurrentPrincipal_PrincipalPolicy_NoPrincipal ()
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));
500 #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
502 [Ignore ("see comment below.")]
503 public void CurrentPrincipal_PrincipalPolicy_UnauthenticatedPrincipal ()
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));
518 public void CurrentPrincipal_PrincipalPolicy_WindowsPrincipal ()
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));
534 public void IPrincipal_CopyOnNewThread ()
536 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("bad"), null);
537 Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.CopyOnNewThread));
539 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("good"), null);
550 [Category("NotDotNet")]
551 public void TestSuspend ()
553 Thread t = new Thread (new ThreadStart (DoCount));
554 t.IsBackground = true;
557 CheckIsRunning ("t1", t);
560 WaitSuspended ("t2", t);
562 CheckIsNotRunning ("t3", t);
565 WaitResumed ("t4", t);
567 CheckIsRunning ("t5", t);
570 TestUtil.WaitForNotAlive (t, "wait13");
571 CheckIsNotRunning ("t6", t);
574 [Category("NotDotNet")]
575 [Category("NotWorking")]
576 public void TestSuspendAbort ()
578 Thread t = new Thread (new ThreadStart (DoCount));
579 t.IsBackground = true;
582 CheckIsRunning ("t1", t);
585 WaitSuspended ("t2", t);
587 CheckIsNotRunning ("t3", t);
592 while (t.IsAlive && n < 200) {
597 Assert.IsTrue (n < 200, "Timeout while waiting for abort");
599 CheckIsNotRunning ("t6", t);
602 void CheckIsRunning (string s, Thread t)
606 Assert.IsTrue (counter > c, s);
609 void CheckIsNotRunning (string s, Thread t)
613 Assert.AreEqual (counter, c, s);
616 void WaitSuspended (string s, Thread t)
619 ThreadState state = t.ThreadState;
620 while ((state & ThreadState.Suspended) == 0) {
621 Assert.IsTrue ((state & ThreadState.SuspendRequested) != 0, s + ": expected SuspendRequested state");
624 Assert.IsTrue (n < 100, s + ": failed to suspend");
625 state = t.ThreadState;
627 Assert.IsTrue ((state & ThreadState.SuspendRequested) == 0, s + ": SuspendRequested state not expected");
630 void WaitResumed (string s, Thread t)
633 while ((t.ThreadState & ThreadState.Suspended) != 0) {
636 Assert.IsTrue (n < 100, s + ": failed to resume");
640 public void DoCount ()
650 public class ThreadStateTest {
656 public void IsBackGround ()
658 Thread t1 = new Thread (new ThreadStart (Start));
659 Assert.AreEqual (ThreadState.Unstarted, t1.ThreadState, "#A1");
660 Assert.IsFalse (t1.IsBackground, "#A2");
663 Assert.AreEqual (ThreadState.Stopped, t1.ThreadState, "#A3");
665 // uncomment when bug #81658 is fixed
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");
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");
684 Assert.AreEqual (ThreadState.Stopped, t2.ThreadState, "#B4");
685 // uncomment when bug #81658 is fixed
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");
700 public class ThreadApartmentTest
707 [Category ("NotWorking")]
708 public void ApartmentState_StoppedThread ()
710 Thread t1 = new Thread (new ThreadStart (Start));
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");
722 Thread t2 = new Thread (new ThreadStart (Start));
723 t2.IsBackground = true;
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");
737 public void ApartmentState_BackGround ()
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");
747 public void TestApartmentState ()
749 Thread t1 = new Thread (new ThreadStart (Start));
750 Thread t2 = new Thread (new ThreadStart (Start));
751 Thread t3 = new Thread (new ThreadStart (Start));
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");
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");
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");
767 bool exception_occured = false;
769 t3.ApartmentState = ApartmentState.Unknown;
772 exception_occured = true;
774 Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Set Invalid");
776 Assert.IsFalse (exception_occured, "Thread3 Set Invalid Exception Occured");
778 Assert.IsTrue (exception_occured, "Thread3 Set Invalid Exception Occured");
782 exception_occured = false;
784 t1.ApartmentState = ApartmentState.STA;
787 exception_occured = true;
789 Assert.IsTrue (exception_occured, "Thread1 Started Invalid Exception Occured");
793 public class TestUtil
795 public static void WaitForNotAlive (Thread t, string s)
797 WhileAlive (t, true, s);
800 public static void WaitForAlive (Thread t, string s)
802 WhileAlive (t, false, s);
805 public static bool WaitForAliveOrStop (Thread t, string s)
807 return WhileAliveOrStop (t, false, s);
810 public static void WhileAlive (Thread t, bool alive, string s)
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);
821 public static bool WhileAliveOrStop (Thread t, bool alive, string s)
823 DateTime ti = DateTime.Now;
824 while (t.IsAlive == alive) {
825 if (t.ThreadState == ThreadState.Stopped)
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);