[System.Net] Add support for .pac proxy config scripts on mac
[mono.git] / mcs / class / System / Test / System.Timers / TimerTest.cs
1 //
2 // TimerTest.cs - NUnit Test Cases for System.Timers.Timer
3 //
4 // Author:
5 //   Kornél Pál <http://www.kornelpal.hu/>
6 //   Robert Jordan <robertj@gmx.net>
7 //
8 // Copyright (C) 2005 Kornél Pál
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using NUnit.Framework;
33 using System;
34 using System.Timers;
35 using ST = System.Threading;
36
37 namespace MonoTests.System.Timers
38 {
39         [TestFixture]
40         public class TimerTest
41         {
42                 Timer timer;
43                 int _elapsedCount;
44
45                 [SetUp]
46                 public void SetUp ()
47                 {
48                         timer = new Timer ();
49                 }
50
51                 [TearDown]
52                 public void TearDown ()
53                 {
54                         timer.Close ();
55                 }
56
57                 [Test]
58                 public void Constructor0 ()
59                 {
60                         Assert.IsTrue (timer.AutoReset, "#1");
61                         Assert.IsFalse (timer.Enabled, "#2");
62                         Assert.AreEqual (100, timer.Interval, "#3");
63                         Assert.IsNull (timer.SynchronizingObject, "#4");
64                 }
65
66                 [Test]
67                 public void Constructor1 ()
68                 {
69                         timer = new Timer (1);
70                         Assert.IsTrue (timer.AutoReset, "#A1");
71                         Assert.IsFalse (timer.Enabled, "#A2");
72                         Assert.AreEqual (1, timer.Interval, "#A3");
73                         Assert.IsNull (timer.SynchronizingObject, "#A4");
74
75                         timer = new Timer (int.MaxValue);
76                         Assert.IsTrue (timer.AutoReset, "#B1");
77                         Assert.IsFalse (timer.Enabled, "#B2");
78                         Assert.AreEqual (int.MaxValue, timer.Interval, "#B3");
79                         Assert.IsNull (timer.SynchronizingObject, "#B4");
80                 }
81
82                 [Test]
83                 public void Constructor1_Interval_Negative ()
84                 {
85                         try {
86                                 new Timer (-1);
87                                 Assert.Fail ("#1");
88                         } catch (ArgumentException ex) {
89                                 // Invalid value -1 for parameter interval
90                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
91                                 Assert.IsNull (ex.InnerException, "#3");
92                                 Assert.IsNotNull (ex.Message, "#4");
93                         }
94                 }
95
96                 [Test]
97                 public void Constructor1_Interval_Zero ()
98                 {
99                         try {
100                                 new Timer (0);
101                                 Assert.Fail ("#1");
102                         } catch (ArgumentException ex) {
103                                 // Invalid value 0 for parameter interval
104                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
105                                 Assert.IsNull (ex.InnerException, "#3");
106                                 Assert.IsNotNull (ex.Message, "#4");
107                         }
108                 }
109
110                 [Test]
111                 public void Constructor1_Interval_Max ()
112                 {
113 #if NET_2_0
114                         try {
115                                 new Timer (0x80000000);
116                                 Assert.Fail ("#A1");
117                         } catch (ArgumentException ex) {
118                                 // Invalid value 2147483648 for parameter interval
119                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
120                                 Assert.IsNull (ex.InnerException, "#A3");
121                                 Assert.IsNotNull (ex.Message, "#A4");
122                         }
123
124                         try {
125                                 new Timer (double.MaxValue);
126                                 Assert.Fail ("#B1");
127                         } catch (ArgumentException ex) {
128                                 // Invalid value 1.79769313486232E+308 for parameter interval
129                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
130                                 Assert.IsNull (ex.InnerException, "#B3");
131                                 Assert.IsNotNull (ex.Message, "#B4");
132                         }
133 #else
134                         timer = new Timer (0x80000000);
135                         Assert.AreEqual (0x80000000, timer.Interval, "#1");
136                         timer = new Timer (double.MaxValue);
137                         Assert.AreEqual (double.MaxValue, timer.Interval, "#2");
138 #endif
139                 }
140
141                 [Test]
142                 public void AutoReset ()
143                 {
144                         Assert.IsTrue (timer.AutoReset, "#1");
145                         timer.AutoReset = false;
146                         Assert.IsFalse (timer.AutoReset, "#2");
147                 }
148
149                 [Test]
150                 public void Interval ()
151                 {
152                         timer.Interval = 1;
153                         Assert.AreEqual (1, timer.Interval, "#1");
154                         timer.Interval = 500;
155                         Assert.AreEqual (500, timer.Interval, "#2");
156                         timer.Interval = double.MaxValue;
157                         Assert.AreEqual (double.MaxValue, timer.Interval, "#3");
158                 }
159
160                 [Test]
161                 public void Interval_Negative ()
162                 {
163                         try {
164                                 timer.Interval = -1;
165                                 Assert.Fail ("#1");
166                         } catch (ArgumentException ex) {
167                                 // '0' is not a valid value for 'Interval'. 'Interval' must be greater than 0
168                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
169                                 Assert.IsNull (ex.InnerException, "#3");
170                                 Assert.IsNotNull (ex.Message, "#4");
171                         }
172                 }
173
174                 [Test]
175                 public void Interval_Zero ()
176                 {
177                         try {
178                                 timer.Interval = 0;
179                                 Assert.Fail ("#1");
180                         } catch (ArgumentException ex) {
181                                 // '0' is not a valid value for 'Interval'. 'Interval' must be greater than 0
182                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
183                                 Assert.IsNull (ex.InnerException, "#3");
184                                 Assert.IsNotNull (ex.Message, "#4");
185                         }
186                 }
187
188                 [Test]
189                 public void StartStopEnabled ()
190                 {
191                         timer.Start ();
192                         Assert.IsTrue (timer.Enabled, "#1");
193                         timer.Stop ();
194                         Assert.IsFalse (timer.Enabled, "#2");
195                 }
196
197                 [Test]
198                 public void CloseEnabled ()
199                 {
200                         Assert.IsFalse (timer.Enabled, "#1");
201                         timer.Enabled = true;
202                         Assert.IsTrue (timer.Enabled, "#2");
203                         timer.Close ();
204                         Assert.IsFalse (timer.Enabled, "#3");
205                 }
206
207                 [Test] // bug #325368
208                 public void EnabledInElapsed ()
209                 {
210                         _elapsedCount = 0;
211                         timer = new Timer (50);
212                         timer.AutoReset = false;
213                         timer.Elapsed += new ElapsedEventHandler (EnabledInElapsed_Elapsed);
214                         timer.Start ();
215
216                         ST.Thread.Sleep (200);
217                         timer.Stop ();
218
219                         Assert.IsTrue (_elapsedCount == 2,  "#1 loss of events");
220                 }
221
222                 [Test]
223                 public void TestRaceCondition ()
224                 {
225                         Assert.IsTrue (new RaceTest (true).Success, "#1");
226                         Assert.IsTrue (new RaceTest (false).Success, "#2");
227                 }
228
229                 void EnabledInElapsed_Elapsed (object sender, ElapsedEventArgs e)
230                 {
231                         _elapsedCount++;
232                         Timer t = sender as Timer;
233                         if (_elapsedCount == 1)
234                                 t.Enabled = true;
235                 }
236         }
237
238         class RaceTest
239         {
240                 const int Threads = 2;
241                 const int Loops = 100;
242
243                 object locker = new object ();
244                 Timer timer;
245                 int counter;
246
247                 public bool Success {
248                         get { return counter > Loops * Threads; }
249                 }
250
251                 public RaceTest (bool autoReset)
252                 {
253                         timer = new Timer ();
254                         timer.AutoReset = autoReset;
255                         timer.Interval = 100;
256                         timer.Elapsed += new ElapsedEventHandler (Tick);
257                         timer.Start ();
258
259                         ST.Thread[] tl = new ST.Thread [Threads];
260
261                         for (int i = 0; i < Threads; i++) {
262                                 tl [i] = new ST.Thread (new ST.ThreadStart (Run));
263                                 tl [i].Start ();
264                         }
265
266                         for (int i = 0; i < Threads; i++) {
267                                 tl [i].Join ();
268                         }
269
270                         ST.Thread.Sleep (1000);
271                 }
272
273                 void Restart ()
274                 {
275                         lock (locker) {
276                                 timer.Stop ();
277                                 timer.Start ();
278                         }
279                         ST.Interlocked.Increment (ref counter);
280                 }
281
282                 void Tick (object sender, ElapsedEventArgs e)
283                 {
284                         Restart ();
285                 }
286
287                 void Run ()
288                 {
289                         for (int i = 0; i < Loops; i++) {
290                                 ST.Thread.Sleep (0);
291                                 Restart ();
292                         }
293                 }
294         }
295 }