imported everything from my branch (which is slightly harmless).
[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 NUnit.Framework;
13 using System;
14 using System.Security.Principal;
15 using System.Threading;
16
17 namespace MonoTests.System.Threading {
18         
19         // These tests seem to hang the 2.0 framework. So they are disabled for now
20         // Don't reenable them until you can run a few thousand times on an SMP box.
21         [Category ("NotWorking")]
22         public class ThreadedPrincipalTest : Assertion {
23
24                 public static void NoPrincipal () 
25                 {
26                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.NoPrincipal);
27                         IPrincipal p = Thread.CurrentPrincipal;
28                         AssertNull ("Thread.CurrentPrincipal-1", p);
29
30                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
31                         AssertNotNull ("Thread.CurrentPrincipal-2", Thread.CurrentPrincipal);
32
33                         Thread.CurrentPrincipal = null;
34                         AssertNull ("Thread.CurrentPrincipal-3", Thread.CurrentPrincipal);
35                         // in this case we can return to null
36                 }
37
38                 public static void UnauthenticatedPrincipal () 
39                 {
40                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.UnauthenticatedPrincipal);
41                         IPrincipal p = Thread.CurrentPrincipal;
42                         AssertNotNull ("Thread.CurrentPrincipal", p);
43                         Assert ("Type", (p is GenericPrincipal));
44                         AssertEquals ("Name", String.Empty, p.Identity.Name);
45                         AssertEquals ("AuthenticationType", String.Empty, p.Identity.AuthenticationType);
46                         Assert ("IsAuthenticated", !p.Identity.IsAuthenticated);
47
48                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
49                         AssertNotNull ("Thread.CurrentPrincipal-2", Thread.CurrentPrincipal);
50
51                         Thread.CurrentPrincipal = null;
52                         AssertNotNull ("Thread.CurrentPrincipal-3", Thread.CurrentPrincipal);
53                         // in this case we can't return to null
54                 }
55
56                 public static void WindowsPrincipal () 
57                 {
58                         AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.WindowsPrincipal);
59                         IPrincipal p = Thread.CurrentPrincipal;
60                         AssertNotNull ("Thread.CurrentPrincipal", p);
61                         Assert ("Type", (p is WindowsPrincipal));
62                         AssertNotNull ("Name", p.Identity.Name);
63                         AssertNotNull ("AuthenticationType", p.Identity.AuthenticationType);
64                         Assert ("IsAuthenticated", p.Identity.IsAuthenticated);
65
66                         // note: we can switch from a WindowsPrincipal to a GenericPrincipal
67                         Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
68                         AssertNotNull ("Thread.CurrentPrincipal-2", Thread.CurrentPrincipal);
69
70                         Thread.CurrentPrincipal = null;
71                         AssertNotNull ("Thread.CurrentPrincipal-3", Thread.CurrentPrincipal);
72                         // in this case we can't return to null
73                 }
74         }
75
76         [TestFixture]
77         [Category ("NotWorking")]
78         public class ThreadTest : Assertion {
79
80                 //Some Classes to test as threads
81                 private class C1Test
82                 {
83                         public int cnt;
84                         public Thread thread1;
85                         public bool endm1;
86                         public bool endm2;
87
88                         public C1Test()
89                         {
90                                 thread1 = (Thread)null;
91                                 this.cnt = 0;
92                                 endm1 = endm2 = false;
93                         }
94                         
95                         public void TestMethod()
96                         {
97                                 while (cnt < 10)
98                                 {
99                                         cnt++;
100                                 }
101                                 endm1 = true;
102                         }
103                         public void TestMethod2()
104                         {
105                                 if (!(thread1==(Thread)null) )
106                                 {
107                                         thread1.Join();
108                                 }
109                                 endm2 = true;
110                         }
111                 }
112
113                 private class C2Test
114                 {
115                         public int cnt;
116                         public bool run = false;
117                         
118                         public C2Test()
119                         {
120                                 this.cnt = 0;
121                         }
122
123                         public void TestMethod()
124                         {
125                                 run = true;
126                                 while (true)
127                                 {
128                                         if (cnt < 1000)
129                                                 cnt++;
130                                         else
131                                                 cnt = 0;
132                                 }
133                         }
134                 }
135                 
136                 private class C3Test
137                 {
138                         public C1Test sub_class;
139                         public Thread sub_thread;
140
141                         public C3Test()
142                         {
143                                 sub_class = new C1Test();
144                                 sub_thread = new Thread(new ThreadStart(sub_class.TestMethod));
145                         }
146
147                         public void TestMethod1()
148                         {
149                                 sub_thread.Start();
150                                 Thread.Sleep (100);
151                                 sub_thread.Abort();
152                         }
153                 }
154                 
155                 private class C4Test
156                 {
157                         public C1Test class1;
158                         public C1Test class2;
159                         public Thread thread1;
160                         public Thread thread2;
161                         public bool T1ON ;
162                         public bool T2ON ;
163
164                         public C4Test()
165                         {
166                                 T1ON = false;
167                                 T2ON = false;
168                                 class1 = new C1Test();
169                                 class2 = new C1Test();
170                                 thread1 = new Thread(new ThreadStart(class1.TestMethod));
171                                 thread2 = new Thread(new ThreadStart(class2.TestMethod));
172                         }
173
174                         public void TestMethod1()
175                         {
176                                 thread1.Start();
177                                 TestUtil.WaitForAlive (thread1, "wait1");
178                                 T1ON = true;
179                                 thread2.Start();
180                                 TestUtil.WaitForAlive (thread2, "wait2");
181                                 T2ON = true;
182                                 thread1.Abort();
183                                 TestUtil.WaitForNotAlive (thread1, "wait3");
184                                 T1ON = false;
185                                 thread2.Abort();
186                                 TestUtil.WaitForNotAlive (thread2, "wait4");
187                                 T2ON = false;
188                         }
189                         
190                         public void TestMethod2()
191                         {
192                                 thread1.Start();
193                                 thread1.Join();
194                         }
195                 }
196
197                 public void TestCtor1()
198                 {                       
199                         C1Test test1 = new C1Test();
200                         try
201                         {
202                                 Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
203                         }
204                         catch (Exception e)
205                         {
206                                 Fail ("#01 Unexpected Exception Thrown: " + e.ToString ());
207                         }
208                 }
209
210                 [Category("NotDotNet")]
211                 public void TestStart()
212                 {
213                 {
214                         C1Test test1 = new C1Test();
215                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
216                         try
217                         {
218                                 TestThread.Start();
219                         }
220                         catch (Exception e)
221                         {
222                                 Fail ("#12 Unexpected Exception Thrown: " + e.ToString ());
223                         }
224                         TestThread.Join();
225                         AssertEquals("#13 Thread Not started: ", 10,test1.cnt);
226                 }
227                 {
228                         bool errorThrown = false;
229                         C2Test test1 = new C2Test();
230                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
231                         TestThread.Start();
232                         TestThread.Abort();
233                         try
234                         {
235                                 TestThread.Start();
236                         }
237                         catch(ThreadStateException)
238                         {
239                                 errorThrown = true;
240                         }
241                         Assert ("#14 no ThreadStateException trown", errorThrown);
242                 }
243                 {
244                         C2Test test1 = new C2Test();
245                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
246                         TestThread.Start();
247                         while(!test1.run);
248                         bool started = (TestThread.ThreadState == ThreadState.Running);
249                         AssertEquals("#15 Thread Is not in the correct state: ", started , test1.run);  
250                         TestThread.Abort();
251                 }
252                 }
253
254                 public void TestApartment()
255                 {
256                         C2Test test1 = new C2Test();
257                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
258                         ApartmentState before = TestThread.ApartmentState;
259                         TestThread.Start();
260                         TestUtil.WaitForAlive (TestThread, "wait5");
261                         ApartmentState after = TestThread.ApartmentState;
262                         TestThread.Abort();
263                         AssertEquals("#21 Apartment State Changed when not needed",before,after);
264                 }
265
266                 [Category("NotDotNet")]
267                 public void TestApartmentState()
268                 {
269                         C2Test test1 = new C2Test();
270                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
271                         ApartmentState before = TestThread.ApartmentState;
272                         TestThread.Start();
273                         TestUtil.WaitForAlive (TestThread, "wait6");
274                         ApartmentState after = TestThread.ApartmentState;
275                         TestThread.Abort();
276                         AssertEquals("#31 Apartment State Changed when not needed: ",before,after);
277                 }
278
279                 public void TestPriority1()
280                 {
281                         C2Test test1 = new C2Test();
282                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
283                         try {
284                                 TestThread.Priority=ThreadPriority.BelowNormal;
285                                 ThreadPriority after = TestThread.Priority;
286                                 TestThread.Start();
287                                 TestUtil.WaitForAlive (TestThread, "wait7");
288                                 ThreadPriority before = TestThread.Priority;
289                                 AssertEquals("#41 Unexpected Priority Change: ",before,after);
290                         }
291                         finally {
292                                 TestThread.Abort();
293                         }
294                 }
295
296                 [Test]
297                 public void AbortUnstarted ()
298                 {
299                         C2Test test1 = new C2Test();
300                         Thread th = new Thread (new ThreadStart (test1.TestMethod));
301                         th.Abort ();
302                         th.Start ();
303                 }
304
305                 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
306                 public void TestPriority2()
307                 {
308                         C2Test test1 = new C2Test();
309                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
310                         try {
311                                 AssertEquals("#42 Incorrect Priority in New thread: ",ThreadPriority.Normal, TestThread.Priority);
312                                 TestThread.Start();
313                                 TestUtil.WaitForAliveOrStop (TestThread, "wait8");
314                                 AssertEquals("#43 Incorrect Priority in Started thread: ",ThreadPriority.Normal, TestThread.Priority);
315                         }
316                         finally {
317                                 TestThread.Abort();
318                         }
319                         AssertEquals("#44 Incorrect Priority in Aborted thread: ",ThreadPriority.Normal, TestThread.Priority);
320                 }
321
322                 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
323                 public void TestPriority3()
324                 {
325                         C2Test test1 = new C2Test();
326                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
327                         try {
328                                 TestThread.Start();
329                                 TestThread.Priority = ThreadPriority.Lowest;
330                                 AssertEquals("#45A Incorrect Priority:",ThreadPriority.Lowest,TestThread.Priority);
331                                 TestThread.Priority = ThreadPriority.BelowNormal;
332                                 AssertEquals("#45B Incorrect Priority:",ThreadPriority.BelowNormal,TestThread.Priority);
333                                 TestThread.Priority = ThreadPriority.Normal;
334                                 AssertEquals("#45C Incorrect Priority:",ThreadPriority.Normal,TestThread.Priority);
335                                 TestThread.Priority = ThreadPriority.AboveNormal;
336                                 AssertEquals("#45D Incorrect Priority:",ThreadPriority.AboveNormal,TestThread.Priority);
337                                 TestThread.Priority = ThreadPriority.Highest;
338                                 AssertEquals("#45E Incorrect Priority:",ThreadPriority.Highest,TestThread.Priority);
339                         }
340                         finally {
341                                 TestThread.Abort();
342                         }
343                 }
344
345
346                 public void TestIsBackground1()
347                 {
348                         C2Test test1 = new C2Test();
349                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
350                         try {
351                                 TestThread.Start();
352                                 TestUtil.WaitForAlive (TestThread, "wait9");
353                                 bool state = TestThread.IsBackground;
354                                 Assert("#51 IsBackground not set at the default state: ",!(state));
355                         }
356                         finally {
357                                 TestThread.Abort();
358                         }
359                 }
360
361                 public void TestIsBackground2()
362                 {
363                         C2Test test1 = new C2Test();
364                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
365                         TestThread.IsBackground = true;
366                         try {
367                                 TestThread.Start();
368                         }
369                         finally {
370                                 TestThread.Abort();
371                         }
372                         Assert("#52 Is Background Changed ot Start ",TestThread.IsBackground);
373                 }
374
375
376                 public void TestName()
377                 {
378                         C2Test test1 = new C2Test();
379                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
380                         try {
381                                 TestThread.Start();
382                                 TestUtil.WaitForAlive (TestThread, "wait10");
383                                 string name = TestThread.Name;
384                                 AssertEquals("#61 Name set when mustn't be set: ", name, (string)null);
385                                 string newname = "Testing....";
386                                 TestThread.Name = newname;
387                                 AssertEquals("#62 Name not set when must be set: ",TestThread.Name,newname);
388                         }
389                         finally {
390                                 TestThread.Abort();
391                         }
392                 }
393
394                 [Category("NotDotNet")]
395                 public void TestNestedThreads1()
396                 {
397                         C3Test  test1 = new C3Test();
398                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
399                         try {
400                                 TestThread.Start();
401                                 TestUtil.WaitForAlive (TestThread, "wait11");
402                         }
403                         catch(Exception e) {
404                                 Fail("#71 Unexpected Exception" + e.Message);
405                         }
406                         finally {
407                                 TestThread.Abort();
408                         }
409                 }
410
411                 public void TestNestedThreads2()
412                 {
413                         C4Test test1 = new C4Test();
414                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
415                         try {
416                                 TestThread.Start();
417                         }
418                         catch(Exception e) {
419                                 Fail("#81 Unexpected Exception" + e.ToString());
420                         }
421                         finally {
422                                 TestThread.Abort();
423                         }
424                 }
425
426                 
427                 public void TestJoin1()
428                 {
429                         C1Test test1 = new C1Test();
430                         C1Test test2 = new C1Test();
431                         Thread thread1 = new Thread(new ThreadStart(test1.TestMethod));
432                         Thread thread2 = new Thread(new ThreadStart(test1.TestMethod2));
433                         try
434                         {
435                                 thread1.Start();
436                                 thread2.Start();
437                                 thread2.Join();
438                         }
439                         catch(Exception e)
440                         {
441                                 Fail("#91 Unexpected Exception " + e.ToString());
442                         }
443                         finally
444                         {
445                                 thread1.Abort();
446                                 thread2.Abort();
447                         }
448                 }
449                 
450                 public void TestThreadState()
451                 {
452                         //TODO: Test The rest of the possible transitions
453                         C2Test test1 = new C2Test();
454                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
455                         AssertEquals("#101 Wrong Thread State",ThreadState.Unstarted,TestThread.ThreadState);
456                         try {
457                                 TestThread.Start();
458                                 //while(!TestThread.IsAlive); //In the MS Documentation this is not necessary
459                                                                                           //but in the MS SDK it is
460                                 Assert("#102 Wrong Thread State: " + TestThread.ThreadState.ToString(), TestThread.ThreadState == ThreadState.Running || (TestThread.ThreadState & ThreadState.Unstarted) != 0);
461                         }
462                         finally {
463                                 TestThread.Abort();
464                         }
465                         
466                         TestUtil.WaitForNotAlive (TestThread, "wait12");
467                         // Docs say state will be Stopped, but Aborted happens sometimes (?)
468                         Assert("#103 Wrong Thread State: " + TestThread.ThreadState.ToString(), (ThreadState.Stopped & TestThread.ThreadState) != 0 
469                                 || (ThreadState.Aborted & TestThread.ThreadState) != 0);
470                 } 
471
472                 [Test]
473                 public void CurrentPrincipal_PrincipalPolicy_NoPrincipal () 
474                 {
475                         // note: switching from PrincipalPolicy won't work inside the same thread
476                         // because as soon as a Principal object is created the Policy doesn't matter anymore
477                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.NoPrincipal));
478                         try {
479                                 t.Start ();
480                                 t.Join ();
481                         }
482                         catch {
483                                 t.Abort ();
484                         }
485                 }
486
487                 [Test]
488                 public void CurrentPrincipal_PrincipalPolicy_UnauthenticatedPrincipal () 
489                 {
490                         // note: switching from PrincipalPolicy won't work inside the same thread
491                         // because as soon as a Principal object is created the Policy doesn't matter anymore
492                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.UnauthenticatedPrincipal));
493                         try {
494                                 t.Start ();
495                                 t.Join ();
496                         }
497                         catch {
498                                 t.Abort ();
499                         }
500                 }
501
502                 [Test]
503                 public void CurrentPrincipal_PrincipalPolicy_WindowsPrincipal () 
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.WindowsPrincipal));
508                         try {
509                                 t.Start ();
510                                 t.Join ();
511                         }
512                         catch {
513                                 t.Abort ();
514                         }
515                 }
516                 
517                 int counter = 0;
518                 
519                 [Category("NotDotNet")]
520                 public void TestSuspend ()
521                 {
522                         Thread t = new Thread (new ThreadStart (DoCount));
523                         t.IsBackground = true;
524                         t.Start ();
525                         
526                         CheckIsRunning ("t1", t);
527                         
528                         t.Suspend ();
529                         WaitSuspended ("t2", t);
530                         
531                         CheckIsNotRunning ("t3", t);
532                         
533                         t.Resume ();
534                         WaitResumed ("t4", t);
535                         
536                         CheckIsRunning ("t5", t);
537                         
538                         t.Abort ();
539                         TestUtil.WaitForNotAlive (t, "wait13");
540                         CheckIsNotRunning ("t6", t);
541                 }
542                 
543                 [Category("NotDotNet")]
544                 [Category("NotWorking")]
545                 public void TestSuspendAbort ()
546                 {
547                         Thread t = new Thread (new ThreadStart (DoCount));
548                         t.IsBackground = true;
549                         t.Start ();
550                         
551                         CheckIsRunning ("t1", t);
552                         
553                         t.Suspend ();
554                         WaitSuspended ("t2", t);
555                         
556                         CheckIsNotRunning ("t3", t);
557                         
558                         t.Abort ();
559                         
560                         int n=0;
561                         while (t.IsAlive && n < 200) {
562                                 Thread.Sleep (10);
563                                 n++;
564                         }
565                         
566                         Assert ("Timeout while waiting for abort", n < 200);
567                         
568                         CheckIsNotRunning ("t6", t);
569                 }               
570                 
571                 void CheckIsRunning (string s, Thread t)
572                 {
573                         int c = counter;
574                         Thread.Sleep (100);
575                         Assert (s, counter > c);
576                 }
577                 
578                 void CheckIsNotRunning (string s, Thread t)
579                 {
580                         int c = counter;
581                         Thread.Sleep (100);
582                         Assert (s, counter == c);
583                 }
584                 
585                 void WaitSuspended (string s, Thread t)
586                 {
587                         int n=0;
588                         ThreadState state = t.ThreadState;
589                         while ((state & ThreadState.Suspended) == 0) {
590                                 Assert (s + ": expected SuspendRequested state", (state & ThreadState.SuspendRequested) != 0);
591                                 Thread.Sleep (10);
592                                 n++;
593                                 Assert (s + ": failed to suspend", n < 100);
594                                 state = t.ThreadState;
595                         }
596                         Assert (s + ": SuspendRequested state not expected", (state & ThreadState.SuspendRequested) == 0);
597                 }
598                 
599                 void WaitResumed (string s, Thread t)
600                 {
601                         int n=0;
602                         while ((t.ThreadState & ThreadState.Suspended) != 0) {
603                                 Thread.Sleep (10);
604                                 n++;
605                                 Assert (s + ": failed to resume", n < 100);
606                         }
607                 }
608                 
609                 public void DoCount ()
610                 {
611                         while (true) {
612                                 counter++;
613                                 Thread.Sleep (1);
614                         }
615                 }
616         }
617         
618         public class TestUtil
619         {
620                 public static void WaitForNotAlive (Thread t, string s)
621                 {
622                         WhileAlive (t, true, s);
623                 }
624                 
625                 public static void WaitForAlive (Thread t, string s)
626                 {
627                         WhileAlive (t, false, s);
628                 }
629                 
630                 public static bool WaitForAliveOrStop (Thread t, string s)
631                 {
632                         return WhileAliveOrStop (t, false, s);
633                 }
634                 
635                 public static void WhileAlive (Thread t, bool alive, string s)
636                 {
637                         DateTime ti = DateTime.Now;
638                         while (t.IsAlive == alive) {
639                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
640                                         if (alive) Assertion.Fail ("Timeout while waiting for not alive state. " + s);
641                                         else Assertion.Fail ("Timeout while waiting for alive state. " + s);
642                                 }
643                         }
644                 }
645
646                 public static bool WhileAliveOrStop (Thread t, bool alive, string s)
647                 {
648                         DateTime ti = DateTime.Now;
649                         while (t.IsAlive == alive) {
650                                 if (t.ThreadState == ThreadState.Stopped)
651                                         return false;
652
653                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
654                                         if (alive) Assertion.Fail ("Timeout while waiting for not alive state. " + s);
655                                         else Assertion.Fail ("Timeout while waiting for alive state. " + s);
656                                 }
657                         }
658
659                         return true;
660                 }
661         }
662 }