ThreadLocalTests.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #if NET_4_0
  2. //
  3. // ThreadLazyTests.cs
  4. //
  5. // Author:
  6. // Jérémie "Garuma" Laval <[email protected]>
  7. //
  8. // Copyright (c) 2009 Jérémie "Garuma" Laval
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining a copy
  11. // of this software and associated documentation files (the "Software"), to deal
  12. // in the Software without restriction, including without limitation the rights
  13. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. // copies of the Software, and to permit persons to whom the Software is
  15. // furnished to do so, subject to the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be included in
  18. // all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26. // THE SOFTWARE.
  27. using System;
  28. using System.Threading;
  29. using NUnit;
  30. using NUnit.Framework;
  31. #if !MOBILE
  32. using NUnit.Framework.SyntaxHelpers;
  33. #endif
  34. namespace MonoTests.System.Threading
  35. {
  36. [TestFixtureAttribute]
  37. public class ThreadLocalTests
  38. {
  39. ThreadLocal<int> threadLocal;
  40. int nTimes;
  41. [SetUp]
  42. public void Setup ()
  43. {
  44. nTimes = 0;
  45. threadLocal = new ThreadLocal<int> (() => { Interlocked.Increment (ref nTimes); return 42; });
  46. }
  47. [Test]
  48. public void SingleThreadTest ()
  49. {
  50. AssertThreadLocal ();
  51. }
  52. [Test]
  53. public void ThreadedTest ()
  54. {
  55. AssertThreadLocal ();
  56. Thread t = new Thread ((object o) => { Interlocked.Decrement (ref nTimes); AssertThreadLocal (); });
  57. t.Start ();
  58. t.Join ();
  59. }
  60. [Test]
  61. public void InitializeThrowingTest ()
  62. {
  63. int callTime = 0;
  64. threadLocal = new ThreadLocal<int> (() => {
  65. Interlocked.Increment (ref callTime);
  66. throw new ApplicationException ("foo");
  67. });
  68. Exception exception = null;
  69. try {
  70. var foo = threadLocal.Value;
  71. } catch (Exception e) {
  72. exception = e;
  73. }
  74. Assert.IsNotNull (exception, "#1");
  75. Assert.That (exception, Is.TypeOf (typeof (ApplicationException)), "#2");
  76. Assert.AreEqual (1, callTime, "#3");
  77. exception = null;
  78. try {
  79. var foo = threadLocal.Value;
  80. } catch (Exception e) {
  81. exception = e;
  82. }
  83. Assert.IsNotNull (exception, "#4");
  84. Assert.That (exception, Is.TypeOf (typeof (ApplicationException)), "#5");
  85. Assert.AreEqual (1, callTime, "#6");
  86. }
  87. [Test, ExpectedException (typeof (InvalidOperationException))]
  88. [Category ("NotDotNet")] // nunit results in stack overflow
  89. public void MultipleReferenceToValueTest ()
  90. {
  91. threadLocal = new ThreadLocal<int> (() => threadLocal.Value + 1);
  92. var value = threadLocal.Value;
  93. }
  94. [Test]
  95. public void DefaultThreadLocalInitTest ()
  96. {
  97. var local = new ThreadLocal<DateTime> ();
  98. var local2 = new ThreadLocal<object> ();
  99. Assert.AreEqual (default (DateTime), local.Value);
  100. Assert.AreEqual (default (object), local2.Value);
  101. }
  102. [Test, ExpectedException (typeof (ObjectDisposedException))]
  103. public void DisposedOnValueTest ()
  104. {
  105. var tl = new ThreadLocal<int> ();
  106. tl.Dispose ();
  107. var value = tl.Value;
  108. }
  109. [Test, ExpectedException (typeof (ObjectDisposedException))]
  110. public void DisposedOnIsValueCreatedTest ()
  111. {
  112. var tl = new ThreadLocal<int> ();
  113. tl.Dispose ();
  114. var value = tl.IsValueCreated;
  115. }
  116. [Test]
  117. public void PerThreadException ()
  118. {
  119. int callTime = 0;
  120. threadLocal = new ThreadLocal<int> (() => {
  121. if (callTime == 1)
  122. throw new ApplicationException ("foo");
  123. Interlocked.Increment (ref callTime);
  124. return 43;
  125. });
  126. Exception exception = null;
  127. var foo = threadLocal.Value;
  128. bool thread_value_created = false;
  129. Assert.AreEqual (43, foo, "#3");
  130. Thread t = new Thread ((object o) => {
  131. try {
  132. var foo2 = threadLocal.Value;
  133. } catch (Exception e) {
  134. exception = e;
  135. }
  136. // should be false and not throw
  137. thread_value_created = threadLocal.IsValueCreated;
  138. });
  139. t.Start ();
  140. t.Join ();
  141. Assert.AreEqual (false, thread_value_created, "#4");
  142. Assert.IsNotNull (exception, "#5");
  143. Assert.That (exception, Is.TypeOf (typeof (ApplicationException)), "#6");
  144. }
  145. void AssertThreadLocal ()
  146. {
  147. Assert.IsFalse (threadLocal.IsValueCreated, "#1");
  148. Assert.AreEqual (42, threadLocal.Value, "#2");
  149. Assert.IsTrue (threadLocal.IsValueCreated, "#3");
  150. Assert.AreEqual (42, threadLocal.Value, "#4");
  151. Assert.AreEqual (1, nTimes, "#5");
  152. }
  153. }
  154. }
  155. #endif