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