In System.Collections.Generic:
[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("NotWorking")]
211                 [Category("NotDotNet")]
212                 public void TestStart()
213                 {
214                 {
215                         C1Test test1 = new C1Test();
216                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
217                         try
218                         {
219                                 TestThread.Start();
220                         }
221                         catch (Exception e)
222                         {
223                                 Fail ("#12 Unexpected Exception Thrown: " + e.ToString ());
224                         }
225                         TestThread.Join();
226                         AssertEquals("#13 Thread Not started: ", 10,test1.cnt);
227                 }
228                 {
229                         bool errorThrown = false;
230                         C2Test test1 = new C2Test();
231                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
232                         TestThread.Start();
233                         TestThread.Abort();
234                         try
235                         {
236                                 TestThread.Start();
237                         }
238                         catch(ThreadStateException)
239                         {
240                                 errorThrown = true;
241                         }
242                         Assert ("#14 no ThreadStateException trown", errorThrown);
243                 }
244                 {
245                         C2Test test1 = new C2Test();
246                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
247                         TestThread.Start();
248                         while(!test1.run);
249                         bool started = (TestThread.ThreadState == ThreadState.Running);
250                         AssertEquals("#15 Thread Is not in the correct state: ", started , test1.run);  
251                         TestThread.Abort();
252                 }
253                 }
254
255                 public void TestApartment()
256                 {
257                         C2Test test1 = new C2Test();
258                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
259                         ApartmentState before = TestThread.ApartmentState;
260                         TestThread.Start();
261                         TestUtil.WaitForAlive (TestThread, "wait5");
262                         ApartmentState after = TestThread.ApartmentState;
263                         TestThread.Abort();
264                         AssertEquals("#21 Apartment State Changed when not needed",before,after);
265                 }
266
267                 [Category("NotDotNet")]
268                 public void TestApartmentState()
269                 {
270                         C2Test test1 = new C2Test();
271                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
272                         ApartmentState before = TestThread.ApartmentState;
273                         TestThread.Start();
274                         TestUtil.WaitForAlive (TestThread, "wait6");
275                         ApartmentState after = TestThread.ApartmentState;
276                         TestThread.Abort();
277                         AssertEquals("#31 Apartment State Changed when not needed: ",before,after);
278                 }
279
280                 public void TestPriority1()
281                 {
282                         C2Test test1 = new C2Test();
283                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
284                         try {
285                                 TestThread.Priority=ThreadPriority.BelowNormal;
286                                 ThreadPriority after = TestThread.Priority;
287                                 TestThread.Start();
288                                 TestUtil.WaitForAlive (TestThread, "wait7");
289                                 ThreadPriority before = TestThread.Priority;
290                                 AssertEquals("#41 Unexpected Priority Change: ",before,after);
291                         }
292                         finally {
293                                 TestThread.Abort();
294                         }
295                 }
296
297                 [Test]
298                 public void AbortUnstarted ()
299                 {
300                         C2Test test1 = new C2Test();
301                         Thread th = new Thread (new ThreadStart (test1.TestMethod));
302                         th.Abort ();
303                         th.Start ();
304                 }
305
306                 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
307                 public void TestPriority2()
308                 {
309                         C2Test test1 = new C2Test();
310                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
311                         try {
312                                 AssertEquals("#42 Incorrect Priority in New thread: ",ThreadPriority.Normal, TestThread.Priority);
313                                 TestThread.Start();
314                                 TestUtil.WaitForAliveOrStop (TestThread, "wait8");
315                                 AssertEquals("#43 Incorrect Priority in Started thread: ",ThreadPriority.Normal, TestThread.Priority);
316                         }
317                         finally {
318                                 TestThread.Abort();
319                         }
320                         AssertEquals("#44 Incorrect Priority in Aborted thread: ",ThreadPriority.Normal, TestThread.Priority);
321                 }
322
323                 [Category("NotWorking")] // this is a MonoTODO -> no support for Priority
324                 public void TestPriority3()
325                 {
326                         C2Test test1 = new C2Test();
327                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
328                         try {
329                                 TestThread.Start();
330                                 TestThread.Priority = ThreadPriority.Lowest;
331                                 AssertEquals("#45A Incorrect Priority:",ThreadPriority.Lowest,TestThread.Priority);
332                                 TestThread.Priority = ThreadPriority.BelowNormal;
333                                 AssertEquals("#45B Incorrect Priority:",ThreadPriority.BelowNormal,TestThread.Priority);
334                                 TestThread.Priority = ThreadPriority.Normal;
335                                 AssertEquals("#45C Incorrect Priority:",ThreadPriority.Normal,TestThread.Priority);
336                                 TestThread.Priority = ThreadPriority.AboveNormal;
337                                 AssertEquals("#45D Incorrect Priority:",ThreadPriority.AboveNormal,TestThread.Priority);
338                                 TestThread.Priority = ThreadPriority.Highest;
339                                 AssertEquals("#45E Incorrect Priority:",ThreadPriority.Highest,TestThread.Priority);
340                         }
341                         finally {
342                                 TestThread.Abort();
343                         }
344                 }
345
346
347                 public void TestIsBackground1()
348                 {
349                         C2Test test1 = new C2Test();
350                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
351                         try {
352                                 TestThread.Start();
353                                 TestUtil.WaitForAlive (TestThread, "wait9");
354                                 bool state = TestThread.IsBackground;
355                                 Assert("#51 IsBackground not set at the default state: ",!(state));
356                         }
357                         finally {
358                                 TestThread.Abort();
359                         }
360                 }
361
362                 public void TestIsBackground2()
363                 {
364                         C2Test test1 = new C2Test();
365                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
366                         TestThread.IsBackground = true;
367                         try {
368                                 TestThread.Start();
369                         }
370                         finally {
371                                 TestThread.Abort();
372                         }
373                         Assert("#52 Is Background Changed ot Start ",TestThread.IsBackground);
374                 }
375
376
377                 public void TestName()
378                 {
379                         C2Test test1 = new C2Test();
380                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
381                         try {
382                                 TestThread.Start();
383                                 TestUtil.WaitForAlive (TestThread, "wait10");
384                                 string name = TestThread.Name;
385                                 AssertEquals("#61 Name set when mustn't be set: ", name, (string)null);
386                                 string newname = "Testing....";
387                                 TestThread.Name = newname;
388                                 AssertEquals("#62 Name not set when must be set: ",TestThread.Name,newname);
389                         }
390                         finally {
391                                 TestThread.Abort();
392                         }
393                 }
394
395                 [Category("NotDotNet")]
396                 public void TestNestedThreads1()
397                 {
398                         C3Test  test1 = new C3Test();
399                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
400                         try {
401                                 TestThread.Start();
402                                 TestUtil.WaitForAlive (TestThread, "wait11");
403                         }
404                         catch(Exception e) {
405                                 Fail("#71 Unexpected Exception" + e.Message);
406                         }
407                         finally {
408                                 TestThread.Abort();
409                         }
410                 }
411
412                 public void TestNestedThreads2()
413                 {
414                         C4Test test1 = new C4Test();
415                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
416                         try {
417                                 TestThread.Start();
418                         }
419                         catch(Exception e) {
420                                 Fail("#81 Unexpected Exception" + e.ToString());
421                         }
422                         finally {
423                                 TestThread.Abort();
424                         }
425                 }
426
427                 [Category ("NotWorking")]
428                 public void TestJoin1()
429                 {
430                         C1Test test1 = new C1Test();
431                         C1Test test2 = new C1Test();
432                         Thread thread1 = new Thread(new ThreadStart(test1.TestMethod));
433                         Thread thread2 = new Thread(new ThreadStart(test1.TestMethod2));
434                         try
435                         {
436                                 thread1.Start();
437                                 thread2.Start();
438                                 thread2.Join();
439                         }
440                         catch(Exception e)
441                         {
442                                 Fail("#91 Unexpected Exception " + e.ToString());
443                         }
444                         finally
445                         {
446                                 thread1.Abort();
447                                 thread2.Abort();
448                         }
449                 }
450                 
451                 public void TestThreadState()
452                 {
453                         //TODO: Test The rest of the possible transitions
454                         C2Test test1 = new C2Test();
455                         Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
456                         AssertEquals("#101 Wrong Thread State",ThreadState.Unstarted,TestThread.ThreadState);
457                         try {
458                                 TestThread.Start();
459                                 //while(!TestThread.IsAlive); //In the MS Documentation this is not necessary
460                                                                                           //but in the MS SDK it is
461                                 Assert("#102 Wrong Thread State: " + TestThread.ThreadState.ToString(), TestThread.ThreadState == ThreadState.Running || (TestThread.ThreadState & ThreadState.Unstarted) != 0);
462                         }
463                         finally {
464                                 TestThread.Abort();
465                         }
466                         
467                         TestUtil.WaitForNotAlive (TestThread, "wait12");
468                         // Docs say state will be Stopped, but Aborted happens sometimes (?)
469                         Assert("#103 Wrong Thread State: " + TestThread.ThreadState.ToString(), (ThreadState.Stopped & TestThread.ThreadState) != 0 
470                                 || (ThreadState.Aborted & TestThread.ThreadState) != 0);
471                 } 
472
473                 [Test]
474                 [Category ("NotWorking")]
475                 public void CurrentPrincipal_PrincipalPolicy_NoPrincipal () 
476                 {
477                         // note: switching from PrincipalPolicy won't work inside the same thread
478                         // because as soon as a Principal object is created the Policy doesn't matter anymore
479                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.NoPrincipal));
480                         try {
481                                 t.Start ();
482                                 t.Join ();
483                         }
484                         catch {
485                                 t.Abort ();
486                         }
487                 }
488
489                 [Test]
490                 [Category ("NotWorking")]
491                 public void CurrentPrincipal_PrincipalPolicy_UnauthenticatedPrincipal () 
492                 {
493                         // note: switching from PrincipalPolicy won't work inside the same thread
494                         // because as soon as a Principal object is created the Policy doesn't matter anymore
495                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.UnauthenticatedPrincipal));
496                         try {
497                                 t.Start ();
498                                 t.Join ();
499                         }
500                         catch {
501                                 t.Abort ();
502                         }
503                 }
504
505                 [Test]
506                 [Category ("NotWorking")]
507                 public void CurrentPrincipal_PrincipalPolicy_WindowsPrincipal () 
508                 {
509                         // note: switching from PrincipalPolicy won't work inside the same thread
510                         // because as soon as a Principal object is created the Policy doesn't matter anymore
511                         Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.WindowsPrincipal));
512                         try {
513                                 t.Start ();
514                                 t.Join ();
515                         }
516                         catch {
517                                 t.Abort ();
518                         }
519                 }
520                 
521                 int counter = 0;
522                 
523                 [Category("NotDotNet")]
524                 public void TestSuspend ()
525                 {
526                         Thread t = new Thread (new ThreadStart (DoCount));
527                         t.IsBackground = true;
528                         t.Start ();
529                         
530                         CheckIsRunning ("t1", t);
531                         
532                         t.Suspend ();
533                         WaitSuspended ("t2", t);
534                         
535                         CheckIsNotRunning ("t3", t);
536                         
537                         t.Resume ();
538                         WaitResumed ("t4", t);
539                         
540                         CheckIsRunning ("t5", t);
541                         
542                         t.Abort ();
543                         TestUtil.WaitForNotAlive (t, "wait13");
544                         CheckIsNotRunning ("t6", t);
545                 }
546                 
547                 [Category("NotDotNet")]
548                 [Category("NotWorking")]
549                 public void TestSuspendAbort ()
550                 {
551                         Thread t = new Thread (new ThreadStart (DoCount));
552                         t.IsBackground = true;
553                         t.Start ();
554                         
555                         CheckIsRunning ("t1", t);
556                         
557                         t.Suspend ();
558                         WaitSuspended ("t2", t);
559                         
560                         CheckIsNotRunning ("t3", t);
561                         
562                         t.Abort ();
563                         
564                         int n=0;
565                         while (t.IsAlive && n < 200) {
566                                 Thread.Sleep (10);
567                                 n++;
568                         }
569                         
570                         Assert ("Timeout while waiting for abort", n < 200);
571                         
572                         CheckIsNotRunning ("t6", t);
573                 }               
574                 
575                 void CheckIsRunning (string s, Thread t)
576                 {
577                         int c = counter;
578                         Thread.Sleep (100);
579                         Assert (s, counter > c);
580                 }
581                 
582                 void CheckIsNotRunning (string s, Thread t)
583                 {
584                         int c = counter;
585                         Thread.Sleep (100);
586                         Assert (s, counter == c);
587                 }
588                 
589                 void WaitSuspended (string s, Thread t)
590                 {
591                         int n=0;
592                         ThreadState state = t.ThreadState;
593                         while ((state & ThreadState.Suspended) == 0) {
594                                 Assert (s + ": expected SuspendRequested state", (state & ThreadState.SuspendRequested) != 0);
595                                 Thread.Sleep (10);
596                                 n++;
597                                 Assert (s + ": failed to suspend", n < 100);
598                                 state = t.ThreadState;
599                         }
600                         Assert (s + ": SuspendRequested state not expected", (state & ThreadState.SuspendRequested) == 0);
601                 }
602                 
603                 void WaitResumed (string s, Thread t)
604                 {
605                         int n=0;
606                         while ((t.ThreadState & ThreadState.Suspended) != 0) {
607                                 Thread.Sleep (10);
608                                 n++;
609                                 Assert (s + ": failed to resume", n < 100);
610                         }
611                 }
612                 
613                 public void DoCount ()
614                 {
615                         while (true) {
616                                 counter++;
617                                 Thread.Sleep (1);
618                         }
619                 }
620         }
621         
622         public class TestUtil
623         {
624                 public static void WaitForNotAlive (Thread t, string s)
625                 {
626                         WhileAlive (t, true, s);
627                 }
628                 
629                 public static void WaitForAlive (Thread t, string s)
630                 {
631                         WhileAlive (t, false, s);
632                 }
633                 
634                 public static bool WaitForAliveOrStop (Thread t, string s)
635                 {
636                         return WhileAliveOrStop (t, false, s);
637                 }
638                 
639                 public static void WhileAlive (Thread t, bool alive, string s)
640                 {
641                         DateTime ti = DateTime.Now;
642                         while (t.IsAlive == alive) {
643                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
644                                         if (alive) Assertion.Fail ("Timeout while waiting for not alive state. " + s);
645                                         else Assertion.Fail ("Timeout while waiting for alive state. " + s);
646                                 }
647                         }
648                 }
649
650                 public static bool WhileAliveOrStop (Thread t, bool alive, string s)
651                 {
652                         DateTime ti = DateTime.Now;
653                         while (t.IsAlive == alive) {
654                                 if (t.ThreadState == ThreadState.Stopped)
655                                         return false;
656
657                                 if ((DateTime.Now - ti).TotalSeconds > 10) {
658                                         if (alive) Assertion.Fail ("Timeout while waiting for not alive state. " + s);
659                                         else Assertion.Fail ("Timeout while waiting for alive state. " + s);
660                                 }
661                         }
662
663                         return true;
664                 }
665         }
666 }