ThreadTest.cs 16 KB

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