[System] Make TimerTest.EnabledInElapsed more reliable
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Tue, 7 Jun 2016 15:20:09 +0000 (17:20 +0200)
committerAlexander Köplinger <alex.koeplinger@outlook.com>
Tue, 7 Jun 2016 23:52:59 +0000 (01:52 +0200)
We were seeing intermittent failures on devices like:

```
[FAIL] TimerTest.EnabledInElapsed :   #1 loss of events
  Expected: True
  But was:  False

  at MonoTests.System.Timers.TimerTest.EnabledInElapsed () <0x33b168 + 0x0014f> in <filename unknown>:0
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object , BindingFlags , System.Reflection.Binder , System.Object[] , System.Globalization.CultureInfo ) <0x66d400 + 0x000b7> in <filename unknown>:0
```

Since OS scheduling and GCs can influence the exact timing of the timer intervals sleeping for 200ms is likely just too short.
Instead of bumping the timeout, I decided to rewrite the test to not rely on Thread.Sleep ().
I also added another test which verifies setting AutoResetEvent=false stops the timer event from firing after the first one,
which was implicitly tested before by the other test.

Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=41530

mcs/class/System/Test/System.Timers/TimerTest.cs

index 2b6a95ff768e56529024f14abce4e5f0c7cab5fd..3dd8cf239af06c93b0219b6d7aacabf5b0cef022 100644 (file)
@@ -40,7 +40,6 @@ namespace MonoTests.System.Timers
        public class TimerTest
        {
                Timer timer;
-               int _elapsedCount;
 
                [SetUp]
                public void SetUp ()
@@ -287,19 +286,46 @@ namespace MonoTests.System.Timers
                        Assert.IsFalse (timer.Enabled, "#3");
                }
 
-               [Test] // bug #325368
+               [Test] // bug https://bugzilla.novell.com/show_bug.cgi?id=325368
                public void EnabledInElapsed ()
                {
-                       _elapsedCount = 0;
+                       var elapsedCount = 0;
+                       var mre = new ST.ManualResetEventSlim ();
                        timer = new Timer (50);
                        timer.AutoReset = false;
-                       timer.Elapsed += new ElapsedEventHandler (EnabledInElapsed_Elapsed);
+                       timer.Elapsed += (s, e) =>
+                       {
+                               elapsedCount++;
+                               if (elapsedCount == 1)
+                                       timer.Enabled = true;
+                               else if (elapsedCount == 2)
+                                       mre.Set ();
+                       };
                        timer.Start ();
 
-                       ST.Thread.Sleep (200);
+                       Assert.IsTrue (mre.Wait (500), "#1 re-enabling timer in Elapsed didn't work");
+                       Assert.AreEqual (2, elapsedCount, "#2 wrong elapsedCount");
                        timer.Stop ();
+               }
 
-                       Assert.IsTrue (_elapsedCount == 2,  "#1 loss of events");
+               [Test]
+               public void AutoResetEventFalseStopsFiringElapsed ()
+               {
+                       var elapsedCount = 0;
+                       var mre = new ST.ManualResetEventSlim ();
+                       timer = new Timer (50);
+                       timer.AutoReset = false;
+                       timer.Elapsed += (s, e) =>
+                       {
+                               elapsedCount++;
+                               if (elapsedCount > 1)
+                                       mre.Set ();
+                       };
+                       timer.Start ();
+
+                       Assert.IsFalse (mre.Wait (500), "#1 AutoResetEvent=false didn't stop firing Elapsed, elapsedCount=" + elapsedCount);
+                       Assert.AreEqual (1, elapsedCount, "#2 wrong elapsedCount");
+                       timer.Stop ();
                }
 
                [Test]
@@ -308,14 +334,6 @@ namespace MonoTests.System.Timers
                        Assert.IsTrue (new RaceTest (true).Success, "#1");
                        Assert.IsTrue (new RaceTest (false).Success, "#2");
                }
-
-               void EnabledInElapsed_Elapsed (object sender, ElapsedEventArgs e)
-               {
-                       _elapsedCount++;
-                       Timer t = sender as Timer;
-                       if (_elapsedCount == 1)
-                               t.Enabled = true;
-               }
        }
 
        class RaceTest