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