ThreadTest.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  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 System;
  12. using System.Globalization;
  13. using System.Security.Principal;
  14. using System.Threading;
  15. using NUnit.Framework;
  16. namespace MonoTests.System.Threading
  17. {
  18. // These tests seem to hang the 2.0 framework. So they are disabled for now
  19. // Don't reenable them until you can run a few thousand times on an SMP box.
  20. [Category ("NotWorking")]
  21. public class ThreadedPrincipalTest
  22. {
  23. public static void NoPrincipal ()
  24. {
  25. #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
  26. AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.NoPrincipal);
  27. #endif
  28. IPrincipal p = Thread.CurrentPrincipal;
  29. Assert.IsNull (p, "#1");
  30. Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
  31. Assert.IsNotNull (Thread.CurrentPrincipal, "#2");
  32. Thread.CurrentPrincipal = null;
  33. Assert.IsNull (Thread.CurrentPrincipal, "#3");
  34. // in this case we can return to null
  35. }
  36. #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
  37. public static void UnauthenticatedPrincipal ()
  38. {
  39. AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.UnauthenticatedPrincipal);
  40. IPrincipal p = Thread.CurrentPrincipal;
  41. Assert.IsNotNull (p, "#1");
  42. Assert.IsTrue ((p is GenericPrincipal), "#2");
  43. Assert.AreEqual (String.Empty, p.Identity.Name, "#3");
  44. Assert.AreEqual (String.Empty, p.Identity.AuthenticationType, "#4");
  45. Assert.IsFalse (p.Identity.IsAuthenticated, "#5");
  46. Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
  47. Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
  48. Thread.CurrentPrincipal = null;
  49. Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
  50. // in this case we can't return to null
  51. }
  52. public static void WindowsPrincipal ()
  53. {
  54. AppDomain.CurrentDomain.SetPrincipalPolicy (PrincipalPolicy.WindowsPrincipal);
  55. IPrincipal p = Thread.CurrentPrincipal;
  56. Assert.IsNotNull (p, "#1");
  57. Assert.IsTrue ((p is WindowsPrincipal), "#2");
  58. Assert.IsNotNull (p.Identity.Name, "#3");
  59. Assert.IsNotNull (p.Identity.AuthenticationType, "#4");
  60. Assert.IsTrue (p.Identity.IsAuthenticated, "#5");
  61. // note: we can switch from a WindowsPrincipal to a GenericPrincipal
  62. Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("mono"), null);
  63. Assert.IsNotNull (Thread.CurrentPrincipal, "#6");
  64. Thread.CurrentPrincipal = null;
  65. Assert.IsNotNull (Thread.CurrentPrincipal, "#7");
  66. // in this case we can't return to null
  67. }
  68. #endif // TARGET_JVM
  69. public static void CopyOnNewThread ()
  70. {
  71. Assert.IsNotNull (Thread.CurrentPrincipal, "#1");
  72. Assert.AreEqual ("good", Thread.CurrentPrincipal.Identity.Name, "#2");
  73. }
  74. }
  75. [TestFixture]
  76. public class ThreadTest
  77. {
  78. static bool is_win32;
  79. static bool is_mono;
  80. static ThreadTest ()
  81. {
  82. switch (Environment.OSVersion.Platform) {
  83. case PlatformID.Win32NT:
  84. case PlatformID.Win32S:
  85. case PlatformID.Win32Windows:
  86. case PlatformID.WinCE:
  87. is_win32 = true;
  88. break;
  89. }
  90. // check a class in mscorlib to determine if we're running on Mono
  91. if (Type.GetType ("System.MonoType", false) != null)
  92. is_mono = true;
  93. }
  94. //Some Classes to test as threads
  95. private class C1Test
  96. {
  97. public int cnt;
  98. public Thread thread1;
  99. public bool endm1;
  100. public bool endm2;
  101. public C1Test()
  102. {
  103. thread1 = (Thread)null;
  104. this.cnt = 0;
  105. endm1 = endm2 = false;
  106. }
  107. public void TestMethod()
  108. {
  109. while (cnt < 10)
  110. {
  111. cnt++;
  112. }
  113. endm1 = true;
  114. }
  115. public void TestMethod2()
  116. {
  117. if (!(thread1==(Thread)null) )
  118. {
  119. thread1.Join();
  120. }
  121. endm2 = true;
  122. }
  123. }
  124. private class C2Test
  125. {
  126. public int cnt;
  127. public bool run = false;
  128. public C2Test()
  129. {
  130. this.cnt = 0;
  131. }
  132. public void TestMethod()
  133. {
  134. run = true;
  135. while (true)
  136. {
  137. if (cnt < 1000)
  138. cnt++;
  139. else
  140. cnt = 0;
  141. }
  142. }
  143. }
  144. private class C3Test
  145. {
  146. public C1Test sub_class;
  147. public Thread sub_thread;
  148. public C3Test()
  149. {
  150. sub_class = new C1Test();
  151. sub_thread = new Thread(new ThreadStart(sub_class.TestMethod));
  152. }
  153. public void TestMethod1()
  154. {
  155. sub_thread.Start();
  156. Thread.Sleep (100);
  157. sub_thread.Abort();
  158. }
  159. }
  160. private class C4Test
  161. {
  162. public C1Test class1;
  163. public C1Test class2;
  164. public Thread thread1;
  165. public Thread thread2;
  166. public bool T1ON ;
  167. public bool T2ON ;
  168. public C4Test()
  169. {
  170. T1ON = false;
  171. T2ON = false;
  172. class1 = new C1Test();
  173. class2 = new C1Test();
  174. thread1 = new Thread(new ThreadStart(class1.TestMethod));
  175. thread2 = new Thread(new ThreadStart(class2.TestMethod));
  176. }
  177. public void TestMethod1()
  178. {
  179. thread1.Start();
  180. TestUtil.WaitForAlive (thread1, "wait1");
  181. T1ON = true;
  182. thread2.Start();
  183. TestUtil.WaitForAlive (thread2, "wait2");
  184. T2ON = true;
  185. thread1.Abort();
  186. TestUtil.WaitForNotAlive (thread1, "wait3");
  187. T1ON = false;
  188. thread2.Abort();
  189. TestUtil.WaitForNotAlive (thread2, "wait4");
  190. T2ON = false;
  191. }
  192. public void TestMethod2()
  193. {
  194. thread1.Start();
  195. thread1.Join();
  196. }
  197. }
  198. [Test]
  199. public void TestCtor1()
  200. {
  201. C1Test test1 = new C1Test();
  202. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  203. }
  204. [Test] // bug #325566
  205. public void GetHashCodeTest ()
  206. {
  207. C1Test test1 = new C1Test ();
  208. Thread tA = new Thread (new ThreadStart (test1.TestMethod));
  209. int hA1 = tA.GetHashCode ();
  210. #if NET_2_0
  211. Assert.IsTrue (hA1 > 0, "#A1");
  212. #endif
  213. tA.Start ();
  214. int hA2 = tA.GetHashCode ();
  215. Assert.AreEqual (hA1, hA2, "#A2");
  216. tA.Join ();
  217. int hA3 = tA.GetHashCode ();
  218. Assert.AreEqual (hA1, hA3, "#A3");
  219. #if NET_2_0
  220. Assert.AreEqual (hA1, tA.ManagedThreadId, "#A4");
  221. #endif
  222. test1 = new C1Test ();
  223. Thread tB = new Thread (new ThreadStart (test1.TestMethod));
  224. int hB1 = tB.GetHashCode ();
  225. #if NET_2_0
  226. Assert.IsTrue (hB1 > 0, "#B1");
  227. #endif
  228. tB.Start ();
  229. int hB2 = tB.GetHashCode ();
  230. Assert.AreEqual (hB1, hB2, "#B2");
  231. tB.Join ();
  232. int hB3 = tB.GetHashCode ();
  233. Assert.AreEqual (hB1, hB3, "#B3");
  234. #if NET_2_0
  235. Assert.AreEqual (hB1, tB.ManagedThreadId, "#B4");
  236. #endif
  237. Assert.IsFalse (hA2 == hB2, "#B5");
  238. }
  239. #if NET_2_0
  240. [Test] // bug #82700
  241. public void ManagedThreadId ()
  242. {
  243. C1Test test1 = new C1Test ();
  244. Thread t1 = new Thread (new ThreadStart (test1.TestMethod));
  245. int mtA1 = t1.ManagedThreadId;
  246. t1.Start ();
  247. int mtA2 = t1.ManagedThreadId;
  248. t1.Join ();
  249. int mtA3 = t1.ManagedThreadId;
  250. Assert.AreEqual (mtA1, mtA2, "#A1");
  251. Assert.AreEqual (mtA2, mtA3, "#A2");
  252. test1 = new C1Test ();
  253. Thread t2 = new Thread (new ThreadStart (test1.TestMethod));
  254. int mtB1 = t2.ManagedThreadId;
  255. t2.Start ();
  256. int mtB2 = t2.ManagedThreadId;
  257. t2.Join ();
  258. int mtB3 = t2.ManagedThreadId;
  259. Assert.AreEqual (mtB1, mtB2, "#B1");
  260. Assert.AreEqual (mtB2, mtB3, "#B2");
  261. Assert.IsFalse (mtB1 == mtA1, "#B3");
  262. }
  263. #endif
  264. [Test]
  265. [Category ("NotDotNet")] // it hangs.
  266. public void TestStart()
  267. {
  268. if (is_win32 && is_mono)
  269. Assert.Fail ("This test fails on Win32. The test should be fixed.");
  270. {
  271. C1Test test1 = new C1Test();
  272. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  273. TestThread.Start();
  274. TestThread.Join();
  275. Assert.AreEqual (10, test1.cnt, "#1");
  276. }
  277. {
  278. C2Test test1 = new C2Test();
  279. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  280. TestThread.Start();
  281. TestThread.Abort();
  282. try {
  283. TestThread.Start();
  284. Assert.Fail ("#2");
  285. } catch (ThreadStateException) {
  286. }
  287. }
  288. {
  289. C2Test test1 = new C2Test();
  290. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  291. TestThread.Start();
  292. while (!test1.run) {
  293. }
  294. bool started = (TestThread.ThreadState == ThreadState.Running);
  295. Assert.AreEqual (started, test1.run, "#15 Thread Is not in the correct state: ");
  296. TestThread.Abort();
  297. }
  298. }
  299. [Test]
  300. public void TestApartmentState ()
  301. {
  302. if (is_win32 && is_mono)
  303. Assert.Fail ("This test fails on mono on win32. Our runtime should be fixed.");
  304. C2Test test1 = new C2Test();
  305. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  306. Assert.AreEqual (ApartmentState.Unknown, TestThread.ApartmentState, "#1");
  307. TestThread.Start();
  308. TestUtil.WaitForAlive (TestThread, "wait5");
  309. #if NET_2_0
  310. Assert.AreEqual (ApartmentState.MTA, TestThread.ApartmentState, "#2");
  311. #else
  312. Assert.AreEqual (ApartmentState.Unknown, TestThread.ApartmentState, "#3");
  313. #endif
  314. TestThread.Abort();
  315. }
  316. [Test]
  317. public void TestPriority1()
  318. {
  319. if (is_win32 && is_mono)
  320. Assert.Fail ("This test fails on mono on Win32. Our runtime should be fixed.");
  321. C2Test test1 = new C2Test();
  322. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  323. try {
  324. TestThread.Priority=ThreadPriority.BelowNormal;
  325. ThreadPriority after = TestThread.Priority;
  326. TestThread.Start();
  327. TestUtil.WaitForAlive (TestThread, "wait7");
  328. ThreadPriority before = TestThread.Priority;
  329. Assert.AreEqual (before, after, "#41 Unexpected Priority Change: ");
  330. } finally {
  331. TestThread.Abort();
  332. }
  333. }
  334. [Test]
  335. [Category ("NotDotNet")] // on MS, Thread is still in AbortRequested state when Start is invoked
  336. public void AbortUnstarted ()
  337. {
  338. C2Test test1 = new C2Test();
  339. Thread th = new Thread (new ThreadStart (test1.TestMethod));
  340. th.Abort ();
  341. th.Start ();
  342. }
  343. [Test]
  344. [Category ("NotDotNet")] // on MS, ThreadState is immediately Stopped after Abort
  345. [Category ("NotWorking")] // this is a MonoTODO -> no support for Priority
  346. public void TestPriority2()
  347. {
  348. C2Test test1 = new C2Test();
  349. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  350. try {
  351. Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#42 Incorrect Priority in New thread: ");
  352. TestThread.Start();
  353. TestUtil.WaitForAliveOrStop (TestThread, "wait8");
  354. Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#43 Incorrect Priority in Started thread: ");
  355. } finally {
  356. TestThread.Abort();
  357. }
  358. Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#44 Incorrect Priority in Aborted thread: ");
  359. }
  360. [Test]
  361. [Category ("NotWorking")] // this is a MonoTODO -> no support for Priority
  362. public void TestPriority3()
  363. {
  364. C2Test test1 = new C2Test();
  365. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  366. try {
  367. TestThread.Start();
  368. TestThread.Priority = ThreadPriority.Lowest;
  369. Assert.AreEqual (ThreadPriority.Lowest, TestThread.Priority, "#45A Incorrect Priority:");
  370. TestThread.Priority = ThreadPriority.BelowNormal;
  371. Assert.AreEqual (ThreadPriority.BelowNormal, TestThread.Priority, "#45B Incorrect Priority:");
  372. TestThread.Priority = ThreadPriority.Normal;
  373. Assert.AreEqual (ThreadPriority.Normal, TestThread.Priority, "#45C Incorrect Priority:");
  374. TestThread.Priority = ThreadPriority.AboveNormal;
  375. Assert.AreEqual (ThreadPriority.AboveNormal, TestThread.Priority, "#45D Incorrect Priority:");
  376. TestThread.Priority = ThreadPriority.Highest;
  377. Assert.AreEqual (ThreadPriority.Highest, TestThread.Priority, "#45E Incorrect Priority:");
  378. }
  379. finally {
  380. TestThread.Abort();
  381. }
  382. }
  383. [Test]
  384. public void TestIsBackground1 ()
  385. {
  386. if (is_win32 && is_mono)
  387. Assert.Fail ("This test fails on mono on Win32. Our runtime should be fixed.");
  388. C2Test test1 = new C2Test();
  389. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  390. try {
  391. TestThread.Start();
  392. TestUtil.WaitForAlive (TestThread, "wait9");
  393. bool state = TestThread.IsBackground;
  394. Assert.IsFalse (state, "#51 IsBackground not set at the default state: ");
  395. } finally {
  396. TestThread.Abort();
  397. }
  398. }
  399. [Test]
  400. [Category ("NotDotNet")] // on MS, ThreadState is immediately Stopped after Abort
  401. public void TestIsBackground2 ()
  402. {
  403. C2Test test1 = new C2Test();
  404. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  405. TestThread.IsBackground = true;
  406. try {
  407. TestThread.Start();
  408. } finally {
  409. TestThread.Abort();
  410. }
  411. Assert.IsTrue (TestThread.IsBackground, "#52 Is Background Changed to Start ");
  412. }
  413. [Test]
  414. public void TestName()
  415. {
  416. if (is_win32 && is_mono)
  417. Assert.Fail ("This test fails on mono on Win32. Our runtime should be fixed.");
  418. C2Test test1 = new C2Test();
  419. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  420. try {
  421. TestThread.Start();
  422. TestUtil.WaitForAlive (TestThread, "wait10");
  423. string name = TestThread.Name;
  424. Assert.IsNull (name, "#61 Name set when mustn't be set: ");
  425. string newname = "Testing....";
  426. TestThread.Name = newname;
  427. Assert.AreEqual (newname, TestThread.Name, "#62 Name not set when must be set: ");
  428. } finally {
  429. TestThread.Abort();
  430. }
  431. }
  432. [Test]
  433. public void TestNestedThreads1()
  434. {
  435. C3Test test1 = new C3Test();
  436. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
  437. try {
  438. TestThread.Start();
  439. TestUtil.WaitForAlive (TestThread, "wait11");
  440. } finally {
  441. TestThread.Abort();
  442. }
  443. }
  444. [Test]
  445. public void TestNestedThreads2()
  446. {
  447. C4Test test1 = new C4Test();
  448. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod1));
  449. try {
  450. TestThread.Start();
  451. } finally {
  452. TestThread.Abort();
  453. }
  454. }
  455. [Test]
  456. public void TestJoin1()
  457. {
  458. C1Test test1 = new C1Test();
  459. C1Test test2 = new C1Test();
  460. Thread thread1 = new Thread(new ThreadStart(test1.TestMethod));
  461. Thread thread2 = new Thread(new ThreadStart(test1.TestMethod2));
  462. try {
  463. thread1.Start();
  464. thread2.Start();
  465. thread2.Join();
  466. } finally {
  467. thread1.Abort();
  468. thread2.Abort();
  469. }
  470. }
  471. [Test]
  472. public void TestThreadState ()
  473. {
  474. if (is_win32 && is_mono)
  475. Assert.Fail ("This test fails on mono on Win32. Our runtime should be fixed.");
  476. //TODO: Test The rest of the possible transitions
  477. C2Test test1 = new C2Test();
  478. Thread TestThread = new Thread(new ThreadStart(test1.TestMethod));
  479. Assert.AreEqual (ThreadState.Unstarted, TestThread.ThreadState, "#101 Wrong Thread State");
  480. try {
  481. TestThread.Start();
  482. //while(!TestThread.IsAlive); //In the MS Documentation this is not necessary
  483. //but in the MS SDK it is
  484. Assert.IsTrue (TestThread.ThreadState == ThreadState.Running || (TestThread.ThreadState & ThreadState.Unstarted) != 0,
  485. "#102 Wrong Thread State: " + TestThread.ThreadState.ToString ());
  486. } finally {
  487. TestThread.Abort();
  488. }
  489. TestUtil.WaitForNotAlive (TestThread, "wait12");
  490. // Docs say state will be Stopped, but Aborted happens sometimes (?)
  491. Assert.IsTrue ((ThreadState.Stopped & TestThread.ThreadState) != 0 || (ThreadState.Aborted & TestThread.ThreadState) != 0,
  492. "#103 Wrong Thread State: " + TestThread.ThreadState.ToString ());
  493. }
  494. [Test]
  495. [Ignore ("see comment below.")]
  496. public void CurrentPrincipal_PrincipalPolicy_NoPrincipal ()
  497. {
  498. // note: switching from PrincipalPolicy won't work inside the same thread
  499. // because as soon as a Principal object is created the Policy doesn't matter anymore
  500. Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.NoPrincipal));
  501. try {
  502. t.Start ();
  503. t.Join ();
  504. } catch {
  505. t.Abort ();
  506. }
  507. }
  508. #if !TARGET_JVM // AppDomain.SetPrincipalPolicy not supported for TARGET_JVM
  509. [Test]
  510. [Ignore ("see comment below.")]
  511. public void CurrentPrincipal_PrincipalPolicy_UnauthenticatedPrincipal ()
  512. {
  513. // note: switching from PrincipalPolicy won't work inside the same thread
  514. // because as soon as a Principal object is created the Policy doesn't matter anymore
  515. Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.UnauthenticatedPrincipal));
  516. try {
  517. t.Start ();
  518. t.Join ();
  519. } catch {
  520. t.Abort ();
  521. }
  522. }
  523. [Test]
  524. public void CurrentPrincipal_PrincipalPolicy_WindowsPrincipal ()
  525. {
  526. // note: switching from PrincipalPolicy won't work inside the same thread
  527. // because as soon as a Principal object is created the Policy doesn't matter anymore
  528. Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.WindowsPrincipal));
  529. try {
  530. t.Start ();
  531. t.Join ();
  532. } catch {
  533. t.Abort ();
  534. }
  535. }
  536. #endif // TARGET_JVM
  537. [Test]
  538. public void IPrincipal_CopyOnNewThread ()
  539. {
  540. Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("bad"), null);
  541. Thread t = new Thread (new ThreadStart (ThreadedPrincipalTest.CopyOnNewThread));
  542. try {
  543. Thread.CurrentPrincipal = new GenericPrincipal (new GenericIdentity ("good"), null);
  544. t.Start ();
  545. t.Join ();
  546. } catch {
  547. t.Abort ();
  548. }
  549. }
  550. int counter = 0;
  551. [Test]
  552. public void TestSuspend ()
  553. {
  554. Thread t = new Thread (new ThreadStart (DoCount));
  555. t.IsBackground = true;
  556. t.Start ();
  557. CheckIsRunning ("t1", t);
  558. t.Suspend ();
  559. WaitSuspended ("t2", t);
  560. CheckIsNotRunning ("t3", t);
  561. t.Resume ();
  562. WaitResumed ("t4", t);
  563. CheckIsRunning ("t5", t);
  564. t.Abort ();
  565. TestUtil.WaitForNotAlive (t, "wait13");
  566. CheckIsNotRunning ("t6", t);
  567. }
  568. [Test]
  569. [Category("NotDotNet")] // On MS, ThreadStateException is thrown on Abort: "Thread is suspended; attempting to abort"
  570. public void TestSuspendAbort ()
  571. {
  572. if (is_win32 && is_mono)
  573. Assert.Fail ("This test fails on Win32. The test should be fixed.");
  574. Thread t = new Thread (new ThreadStart (DoCount));
  575. t.IsBackground = true;
  576. t.Start ();
  577. CheckIsRunning ("t1", t);
  578. t.Suspend ();
  579. WaitSuspended ("t2", t);
  580. CheckIsNotRunning ("t3", t);
  581. t.Abort ();
  582. int n=0;
  583. while (t.IsAlive && n < 200) {
  584. Thread.Sleep (10);
  585. n++;
  586. }
  587. Assert.IsTrue (n < 200, "Timeout while waiting for abort");
  588. CheckIsNotRunning ("t6", t);
  589. }
  590. [Test]
  591. public void Test_Interrupt ()
  592. {
  593. bool interruptedExceptionThrown = false;
  594. ThreadPool.QueueUserWorkItem (Test_Interrupt_Worker, Thread.CurrentThread);
  595. try {
  596. try {
  597. Thread.Sleep (3000);
  598. } finally {
  599. try {
  600. Thread.Sleep (0);
  601. } catch (ThreadInterruptedException) {
  602. Assert.Fail ("ThreadInterruptedException thrown twice");
  603. }
  604. }
  605. } catch (ThreadInterruptedException) {
  606. interruptedExceptionThrown = true;
  607. }
  608. Assert.IsTrue (interruptedExceptionThrown, "ThreadInterruptedException expected.");
  609. }
  610. private void Test_Interrupt_Worker (object o)
  611. {
  612. Thread t = o as Thread;
  613. Thread.Sleep (100);
  614. t.Interrupt ();
  615. }
  616. [Test]
  617. public void Test_InterruptCurrentThread ()
  618. {
  619. bool interruptedExceptionThrown = false;
  620. try {
  621. try {
  622. Thread.CurrentThread.Interrupt ();
  623. } finally {
  624. try {
  625. Thread.Sleep (0);
  626. } catch (ThreadInterruptedException) {
  627. Assert.Fail ("ThreadInterruptedException should not be thrown.");
  628. }
  629. }
  630. } catch (ThreadInterruptedException) {
  631. interruptedExceptionThrown = true;
  632. }
  633. Assert.IsFalse (interruptedExceptionThrown, "ThreadInterruptedException should not be thrown.");
  634. }
  635. void CheckIsRunning (string s, Thread t)
  636. {
  637. int c = counter;
  638. Thread.Sleep (100);
  639. Assert.IsTrue (counter > c, s);
  640. }
  641. void CheckIsNotRunning (string s, Thread t)
  642. {
  643. int c = counter;
  644. Thread.Sleep (100);
  645. Assert.AreEqual (counter, c, s);
  646. }
  647. void WaitSuspended (string s, Thread t)
  648. {
  649. int n=0;
  650. ThreadState state = t.ThreadState;
  651. while ((state & ThreadState.Suspended) == 0) {
  652. Assert.IsTrue ((state & ThreadState.SuspendRequested) != 0, s + ": expected SuspendRequested state");
  653. Thread.Sleep (10);
  654. n++;
  655. Assert.IsTrue (n < 100, s + ": failed to suspend");
  656. state = t.ThreadState;
  657. }
  658. Assert.IsTrue ((state & ThreadState.SuspendRequested) == 0, s + ": SuspendRequested state not expected");
  659. }
  660. void WaitResumed (string s, Thread t)
  661. {
  662. int n=0;
  663. while ((t.ThreadState & ThreadState.Suspended) != 0) {
  664. Thread.Sleep (10);
  665. n++;
  666. Assert.IsTrue (n < 100, s + ": failed to resume");
  667. }
  668. }
  669. public void DoCount ()
  670. {
  671. while (true) {
  672. counter++;
  673. Thread.Sleep (1);
  674. }
  675. }
  676. }
  677. [TestFixture]
  678. public class ThreadStateTest {
  679. void Start ()
  680. {
  681. }
  682. [Test] // bug #81720
  683. public void IsBackGround ()
  684. {
  685. Thread t1 = new Thread (new ThreadStart (Start));
  686. Assert.AreEqual (ThreadState.Unstarted, t1.ThreadState, "#A1");
  687. Assert.IsFalse (t1.IsBackground, "#A2");
  688. t1.Start ();
  689. t1.Join ();
  690. Assert.AreEqual (ThreadState.Stopped, t1.ThreadState, "#A3");
  691. try {
  692. bool isBackGround = t1.IsBackground;
  693. Assert.Fail ("#A4: " + isBackGround.ToString ());
  694. } catch (ThreadStateException ex) {
  695. Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A5");
  696. Assert.IsNull (ex.InnerException, "#A6");
  697. Assert.IsNotNull (ex.Message, "#A7");
  698. }
  699. Thread t2 = new Thread (new ThreadStart (Start));
  700. Assert.AreEqual (ThreadState.Unstarted, t2.ThreadState, "#B1");
  701. t2.IsBackground = true;
  702. Assert.AreEqual (ThreadState.Unstarted | ThreadState.Background, t2.ThreadState, "#B2");
  703. Assert.IsTrue (t2.IsBackground, "#B3");
  704. t2.Start ();
  705. t2.Join ();
  706. Assert.AreEqual (ThreadState.Stopped, t2.ThreadState, "#B4");
  707. try {
  708. bool isBackGround = t2.IsBackground;
  709. Assert.Fail ("#B5: " + isBackGround.ToString ());
  710. } catch (ThreadStateException ex) {
  711. Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B6");
  712. Assert.IsNull (ex.InnerException, "#B7");
  713. Assert.IsNotNull (ex.Message, "#B8");
  714. }
  715. }
  716. }
  717. [TestFixture]
  718. public class ThreadApartmentTest
  719. {
  720. void Start ()
  721. {
  722. }
  723. [Test] // bug #81658
  724. public void ApartmentState_StoppedThread ()
  725. {
  726. Thread t1 = new Thread (new ThreadStart (Start));
  727. t1.Start ();
  728. t1.Join ();
  729. try {
  730. ApartmentState state = t1.ApartmentState;
  731. Assert.Fail ("#A1: " + state.ToString ());
  732. } catch (ThreadStateException ex) {
  733. Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#A2");
  734. Assert.IsNull (ex.InnerException, "#A3");
  735. Assert.IsNotNull (ex.Message, "#A4");
  736. }
  737. Thread t2 = new Thread (new ThreadStart (Start));
  738. t2.IsBackground = true;
  739. t2.Start ();
  740. t2.Join ();
  741. try {
  742. ApartmentState state = t2.ApartmentState;
  743. Assert.Fail ("#B1: " + state.ToString ());
  744. } catch (ThreadStateException ex) {
  745. Assert.AreEqual (typeof (ThreadStateException), ex.GetType (), "#B2");
  746. Assert.IsNull (ex.InnerException, "#B3");
  747. Assert.IsNotNull (ex.Message, "#B4");
  748. }
  749. }
  750. [Test]
  751. public void ApartmentState_BackGround ()
  752. {
  753. Thread t1 = new Thread (new ThreadStart (Start));
  754. t1.IsBackground = true;
  755. Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "#1");
  756. t1.ApartmentState = ApartmentState.STA;
  757. Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "#2");
  758. }
  759. [Test]
  760. public void TestApartmentState ()
  761. {
  762. Thread t1 = new Thread (new ThreadStart (Start));
  763. Thread t2 = new Thread (new ThreadStart (Start));
  764. Thread t3 = new Thread (new ThreadStart (Start));
  765. Assert.AreEqual (ApartmentState.Unknown, t1.ApartmentState, "Thread1 Default");
  766. Assert.AreEqual (ApartmentState.Unknown, t2.ApartmentState, "Thread2 Default");
  767. Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Default");
  768. t1.ApartmentState = ApartmentState.STA;
  769. Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Once");
  770. t1.ApartmentState = ApartmentState.MTA;
  771. Assert.AreEqual (ApartmentState.STA, t1.ApartmentState, "Thread1 Set Twice");
  772. t2.ApartmentState = ApartmentState.MTA;
  773. Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Once");
  774. t2.ApartmentState = ApartmentState.STA;
  775. Assert.AreEqual (ApartmentState.MTA, t2.ApartmentState, "Thread2 Set Twice");
  776. bool exception_occured = false;
  777. try {
  778. t3.ApartmentState = ApartmentState.Unknown;
  779. }
  780. catch (Exception) {
  781. exception_occured = true;
  782. }
  783. Assert.AreEqual (ApartmentState.Unknown, t3.ApartmentState, "Thread3 Set Invalid");
  784. #if NET_2_0
  785. Assert.IsFalse (exception_occured, "Thread3 Set Invalid Exception Occured");
  786. #else
  787. Assert.IsTrue (exception_occured, "Thread3 Set Invalid Exception Occured");
  788. #endif
  789. t1.Start ();
  790. exception_occured = false;
  791. try {
  792. t1.ApartmentState = ApartmentState.STA;
  793. }
  794. catch (Exception) {
  795. exception_occured = true;
  796. }
  797. Assert.IsTrue (exception_occured, "Thread1 Started Invalid Exception Occured");
  798. }
  799. }
  800. public class TestUtil
  801. {
  802. public static void WaitForNotAlive (Thread t, string s)
  803. {
  804. WhileAlive (t, true, s);
  805. }
  806. public static void WaitForAlive (Thread t, string s)
  807. {
  808. WhileAlive (t, false, s);
  809. }
  810. public static bool WaitForAliveOrStop (Thread t, string s)
  811. {
  812. return WhileAliveOrStop (t, false, s);
  813. }
  814. public static void WhileAlive (Thread t, bool alive, string s)
  815. {
  816. DateTime ti = DateTime.Now;
  817. while (t.IsAlive == alive) {
  818. if ((DateTime.Now - ti).TotalSeconds > 10) {
  819. if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
  820. else Assert.Fail ("Timeout while waiting for alive state. " + s);
  821. }
  822. }
  823. }
  824. public static bool WhileAliveOrStop (Thread t, bool alive, string s)
  825. {
  826. DateTime ti = DateTime.Now;
  827. while (t.IsAlive == alive) {
  828. if (t.ThreadState == ThreadState.Stopped)
  829. return false;
  830. if ((DateTime.Now - ti).TotalSeconds > 10) {
  831. if (alive) Assert.Fail ("Timeout while waiting for not alive state. " + s);
  832. else Assert.Fail ("Timeout while waiting for alive state. " + s);
  833. }
  834. }
  835. return true;
  836. }
  837. }
  838. }