From 29d63474bf507b11f95878e5eccc8d46663da0c3 Mon Sep 17 00:00:00 2001 From: "Raf (Raffaele Rialdi)" Date: Thu, 24 Aug 2023 17:35:37 +0200 Subject: [PATCH] Fixes the button holding test randomly failing on Mac (#2121) * Holding button test change to measure effective time elapsed * Making the test async and awaitable from the test suite --- src/devices/Button/tests/ButtonTests.cs | 31 ++++++++++++++++++++----- src/devices/Button/tests/TestButton.cs | 4 ++-- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/devices/Button/tests/ButtonTests.cs b/src/devices/Button/tests/ButtonTests.cs index 02bf7eaa..67ad6ab5 100644 --- a/src/devices/Button/tests/ButtonTests.cs +++ b/src/devices/Button/tests/ButtonTests.cs @@ -3,6 +3,7 @@ using System; using System.Threading; +using System.Threading.Tasks; using Xunit; @@ -47,14 +48,18 @@ namespace Iot.Device.Button.Tests } [Fact] - public void If_Button_Is_Held_Holding_Event_Fires() + public async Task If_Button_Is_Held_Holding_Event_Fires() { bool pressed = false; bool holding = false; bool doublePressed = false; - TestButton button = new TestButton(); + // we set short times to avoid wasting when executing the tests + var debounceTime = TimeSpan.FromMilliseconds(200); + var holdingTime = TimeSpan.FromMilliseconds(400); + TestButton button = new TestButton(debounceTime, holdingTime); button.IsHoldingEnabled = true; + TaskCompletionSource tcs = new TaskCompletionSource(); button.Press += (sender, e) => { @@ -64,6 +69,10 @@ namespace Iot.Device.Button.Tests button.Holding += (sender, e) => { holding = true; + if (e.HoldingState == ButtonHoldingState.Completed) + { + tcs.SetResult(DateTime.Now); + } }; button.DoublePress += (sender, e) => @@ -71,13 +80,21 @@ namespace Iot.Device.Button.Tests doublePressed = true; }; + DateTime now = DateTime.Now; button.PressButton(); - // Wait longer than default holding threshold milliseconds, for the click to be recognized as a holding event. - Thread.Sleep(2100); + Thread.Sleep((int)holdingTime.TotalMilliseconds + 100); button.ReleaseButton(); + // this is only needed to avoid to wait indefinitely in case the code gets broken and the test fail + var firstTask = await Task.WhenAny(tcs.Task, Task.Delay(2 * (int)holdingTime.TotalMilliseconds)); + Assert.True(tcs.Task == firstTask, "holding timeout"); + + // holdingTime is the DateTime retrieved in the holding timer handler + var effectiveHoldingTime = tcs.Task.Result; + + Assert.True(effectiveHoldingTime - now >= holdingTime, "holding"); Assert.True(holding, "holding"); Assert.True(pressed, "pressed"); Assert.False(doublePressed, "doublePressed"); @@ -255,7 +272,8 @@ namespace Iot.Device.Button.Tests bool doublePressed = false; int pressedCounter = 0; - TestButton button = new TestButton(TimeSpan.FromMilliseconds(1000)); + var holdingTime = TimeSpan.FromMilliseconds(2000); + TestButton button = new TestButton(TimeSpan.FromMilliseconds(1000), holdingTime); button.Press += (sender, e) => { @@ -305,7 +323,8 @@ namespace Iot.Device.Button.Tests int pressedCounter = 0; // holding is 2 secs, debounce is 1 sec - TestButton button = new TestButton(TimeSpan.FromMilliseconds(1000)); + var holdingTime = TimeSpan.FromMilliseconds(2000); + TestButton button = new TestButton(TimeSpan.FromMilliseconds(1000), holdingTime); button.IsHoldingEnabled = true; button.Press += (sender, e) => diff --git a/src/devices/Button/tests/TestButton.cs b/src/devices/Button/tests/TestButton.cs index 11982696..f3587223 100644 --- a/src/devices/Button/tests/TestButton.cs +++ b/src/devices/Button/tests/TestButton.cs @@ -12,8 +12,8 @@ namespace Iot.Device.Button.Tests { } - public TestButton(TimeSpan debounceTime) - : base(TimeSpan.FromSeconds(5), TimeSpan.FromMilliseconds(2000), debounceTime) + public TestButton(TimeSpan debounceTime, TimeSpan holdingTime) + : base(TimeSpan.FromSeconds(5), holdingTime, debounceTime) { } -- GitLab