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.Security.Principal;
14 using System.Threading;
16 using NUnit.Framework;
18 namespace MonoTests.System.Threading
20 // These tests seem to hang the 2.0 framework. So they are disabled for now
21 // Don't reenable them until you can run a few thousand times on an SMP box.
22 [Category ("NotWorking")]
23 public class ThreadedPrincipalTest
25 public static void NoPrincipal ()
27 #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
28 AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.NoPrincipal);
30 IPrincipal p = Thread.CurrentPrincipal;
31 Assert.IsNull (p, "#1");
33 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
34 Assert.IsNotNull (Thread.CurrentPrincipal, "#2");
36 Thread.CurrentPrincipal = null;
37 Assert.IsNull (Thread.CurrentPrincipal, "#3");
38 // in this case we can return to null
41 #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
42 public static void UnauthenticatedPrincipal ()
44 AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.UnauthenticatedPrincipal);
45 IPrincipal p = Thread.CurrentPrincipal;
46 Assert.IsNotNull (p, "#1");
47 Assert.IsTrue ((p is GenericPrincipal), "#2");
48 Assert.AreEqual (String.Empty, p.Identity.Name, "#3");
49 Assert.AreEqual (String.Empty, p.Identity.AuthenticationType, "#4");
50 Assert.IsFalse (p.Identity.IsAuthenticated, "#5");
52 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
53 Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
55 Thread.CurrentPrincipal = null;
56 Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
57 // in this case we can't return to null
60 public static void WindowsPrincipal ()
62 AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.WindowsPrincipal);
63 IPrincipal p = Thread.CurrentPrincipal;
64 Assert.IsNotNull (p, "#1");
65 Assert.IsTrue ((p is WindowsPrincipal), "#2");
66 Assert.IsNotNull (p.Identity.Name, "#3");
67 Assert.IsNotNull (p.Identity.AuthenticationType, "#4");
68 Assert.IsTrue (p.Identity.IsAuthenticated, "#5");
70 // note: we can switch from a WindowsPrincipal to a GenericPrincipal
71 Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
72 Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
74 Thread.CurrentPrincipal = null;
75 Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
76 // in this case we can't return to null
80 public static void CopyOnNewThread ()
82 Assert.IsNotNull (Thread.CurrentPrincipal, "#1");
83 Assert.AreEqual ("good", Thread.CurrentPrincipal.Identity.Name, "#2");
88 [Category ("NotWorking")]
89 public class ThreadTest
91 //Some Classes to test as threads
95 public Thread thread1;
101 thread1 = (Thread)null;
103 endm1 = endm2 = false;
106 public void TestMethod()
114 public void TestMethod2()
116 if (!(thread1==(Thread)null) )
127 public bool run = false;
134 public void TestMethod()
149 public C1Test sub_class;
150 public Thread sub_thread;
154 sub_class = new C1Test();
155 sub_thread = new Thread(new ThreadStart(sub_class.TestMethod));
158 public void TestMethod1()
168 public C1Test class1;
169 public C1Test class2;
170 public Thread thread1;
171 public Thread thread2;
179 class1 = new C1Test();
180 class2 = new C1Test();
181 thread1 = new Thread(new ThreadStart(class1.TestMethod));
182 thread2 = new Thread(new ThreadStart(class2.TestMethod));
185 public void TestMethod1()
188 TestUtil.WaitForAlive (thread1, "wait1");
191 TestUtil.WaitForAlive (thread2, "wait2");
194 TestUtil.WaitForNotAlive (thread1, "wait3");
197 TestUtil.WaitForNotAlive (thread2, "wait4");
201 public void TestMethod2()
208 public void TestCtor1()
210 C1Test test1 = new C1Test();
213 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
217 Assert.Fail ("#01 Unexpected Exception Thrown: " + e.ToString ());
221 [Category("NotDotNet")]
222 public void TestStart()
225 C1Test test1 = new C1Test();
226 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
233 Assert.Fail ("#12 Unexpected Exception Thrown: " + e.ToString ());
236 Assert.AreEqual (10, test1.cnt, "#13 Thread Not started");
239 bool errorThrown = false;
240 C2Test test1 = new C2Test();
241 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
248 catch(ThreadStateException)
252 Assert.IsTrue (errorThrown, "#14 no ThreadStateException trown");
255 C2Test test1 = new C2Test();
256 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
259 bool started = (TestThread.ThreadState == ThreadState.Running);
260 Assert.AreEqual (started, test1.run, "#15 Thread Is not in the correct state: ");
265 public void TestApartment()
267 C2Test test1 = new C2Test();
268 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
269 ApartmentState before = TestThread.ApartmentState;
271 TestUtil.WaitForAlive (TestThread, "wait5");
272 ApartmentState after = TestThread.ApartmentState;
274 Assert.AreEqual (before, after, "#21 Apartment State Changed when not needed");
277 [Category("NotDotNet")]
278 public void TestApartmentState()
280 C2Test test1 = new C2Test();
281 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
282 ApartmentState before = TestThread.ApartmentState;
284 TestUtil.WaitForAlive (TestThread, "wait6");
285 ApartmentState after = TestThread.ApartmentState;
287 Assert.AreEqual (before, after, "#31 Apartment State Changed when not needed: ");
290 public void TestPriority1()
292 C2Test test1 = new C2Test();
293 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
295 TestThread.Priority=ThreadPriority.BelowNormal;
296 ThreadPriority after = TestThread.Priority;
298 TestUtil.WaitForAlive (TestThread, "wait7");
299 ThreadPriority before = TestThread.Priority;
300 Assert.AreEqual (before, after, "#41 Unexpected Priority Change: ");
308 public void AbortUnstarted ()
310 C2Test test1 = new C2Test();
311 Thread th = new Thread (new ThreadStart (test1.TestMethod));
316 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
317 public void TestPriority2()
319 C2Test test1 = new C2Test();
320 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
322 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#42 Incorrect Priority in New thread: ");
324 TestUtil.WaitForAliveOrStop (TestThread, "wait8");
325 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#43 Incorrect Priority in Started thread: ");
330 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#44 Incorrect Priority in Aborted thread: ");
333 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
334 public void TestPriority3()
336 C2Test test1 = new C2Test();
337 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
340 TestThread.Priority = ThreadPriority.Lowest;
341 Assert.AreEqual (ThreadPriority.Lowest, TestThread.Priority, "#45A Incorrect Priority:");
342 TestThread.Priority = ThreadPriority.BelowNormal;
343 Assert.AreEqual (ThreadPriority.BelowNormal, TestThread.Priority, "#45B Incorrect Priority:");
344 TestThread.Priority = ThreadPriority.Normal;
345 Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#45C Incorrect Priority:");
346 TestThread.Priority = ThreadPriority.AboveNormal;
347 Assert.AreEqual (ThreadPriority.AboveNormal, TestThread.Priority, "#45D Incorrect Priority:");
348 TestThread.Priority = ThreadPriority.Highest;
349 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 ThreadApartmentTest
657 [Category ("NotWorking")]
658 public void ApartmentState_StoppedThread ()
660 Thread t1 = new Thread (new ThreadStart (Start));
663 Assert.AreEqual (ThreadState.Stopped, t1.ThreadState, "#1");
665 ApartmentState state = t1.ApartmentState;
667 } catch (ThreadStateException) {
672 public void TestApartmentState ()
674 Thread t1 = new Thread (new ThreadStart (Start));
675 Thread t2 = new Thread (new ThreadStart (Start));
676 Thread t3 = new Thread (new ThreadStart (Start));
678 Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "Thread1 Default");
679 Assert.AreEqual (ApartmentState.Unknown, t2.ApartmentState, "Thread2 Default");
680 Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Default");
682 t1.ApartmentState = ApartmentState.STA;
683 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
684 t1.ApartmentState = ApartmentState.MTA;
685 Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Twice");
687 t2.ApartmentState = ApartmentState.MTA;
688 Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Once");
689 t2.ApartmentState = ApartmentState.STA;
690 Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Twice");
692 bool exception_occured = false;
694 t3.ApartmentState = ApartmentState.Unknown;
697 exception_occured = true;
699 Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Set Invalid");
701 Assert.IsFalse (exception_occured, "Thread3 Set Invalid Exception Occured");
703 Assert.IsTrue (exception_occured, "Thread3 Set Invalid Exception Occured");
707 exception_occured = false;
709 t1.ApartmentState = ApartmentState.STA;
712 exception_occured = true;
714 Assert.IsTrue (exception_occured, "Thread1 Started Invalid Exception Occured");
718 public class TestUtil
720 public static void WaitForNotAlive (Thread t, string s)
722 WhileAlive (t, true, s);
725 public static void WaitForAlive (Thread t, string s)
727 WhileAlive (t, false, s);
730 public static bool WaitForAliveOrStop (Thread t, string s)
732 return WhileAliveOrStop (t, false, s);
735 public static void WhileAlive (Thread t, bool alive, string s)
737 DateTime ti = DateTime.Now;
738 while (t.IsAlive == alive) {
739 if ((DateTime.Now - ti).TotalSeconds > 10) {
740 if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
741 else Assert.Fail ("Timeout while waiting for alive state. " + s);
746 public static bool WhileAliveOrStop (Thread t, bool alive, string s)
748 DateTime ti = DateTime.Now;
749 while (t.IsAlive == alive) {
750 if (t.ThreadState == ThreadState.Stopped)
753 if ((DateTime.Now - ti).TotalSeconds > 10) {
754 if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
755 else Assert.Fail ("Timeout while waiting for alive state. " + s);