diff --git a/Feature.Flags.props b/Feature.Flags.props
index 6507c5114..1852d3b8d 100644
--- a/Feature.Flags.props
+++ b/Feature.Flags.props
@@ -23,7 +23,6 @@
$(DefineConstants);FEATURE_RANDOM_ADVANCED
$(DefineConstants);FEATURE_FILESYSTEMWATCHER_ADVANCED
$(DefineConstants);FEATURE_EXCEPTION_HRESULT
- $(DefineConstants);FEATURE_TIMER_COUNT
$(DefineConstants);FEATURE_ZIPFILE_NET7
$(DefineConstants);FEATURE_FILESYSTEM_NET7
$(DefineConstants);FEATURE_FILESYSTEM_SAFEFILEHANDLE
diff --git a/Source/Testably.Abstractions.Interface/ITimeSystem.cs b/Source/Testably.Abstractions.Interface/ITimeSystem.cs
index 8f41f8449..20d684226 100644
--- a/Source/Testably.Abstractions.Interface/ITimeSystem.cs
+++ b/Source/Testably.Abstractions.Interface/ITimeSystem.cs
@@ -21,9 +21,4 @@ public interface ITimeSystem
/// Abstractions for .
///
IThread Thread { get; }
-
- ///
- /// Abstractions for .
- ///
- ITimerFactory Timer { get; }
}
diff --git a/Source/Testably.Abstractions.Interface/TimeSystem/ITimer.cs b/Source/Testably.Abstractions.Interface/TimeSystem/ITimer.cs
deleted file mode 100644
index a27fe49c9..000000000
--- a/Source/Testably.Abstractions.Interface/TimeSystem/ITimer.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System;
-using System.Threading;
-
-namespace Testably.Abstractions.TimeSystem;
-
-///
-/// Abstractions for .
-///
-public interface ITimer : ITimeSystemEntity, IDisposable
-#if FEATURE_ASYNC_DISPOSABLE
- , IAsyncDisposable
-#endif
-{
- ///
- bool Change(int dueTime, int period);
-
- ///
- bool Change(long dueTime, long period);
-
- ///
- bool Change(TimeSpan dueTime, TimeSpan period);
-
- ///
- bool Dispose(WaitHandle notifyObject);
-}
diff --git a/Source/Testably.Abstractions.Interface/TimeSystem/ITimerFactory.cs b/Source/Testably.Abstractions.Interface/TimeSystem/ITimerFactory.cs
deleted file mode 100644
index 6b9538b4e..000000000
--- a/Source/Testably.Abstractions.Interface/TimeSystem/ITimerFactory.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System;
-using System.Threading;
-
-namespace Testably.Abstractions.TimeSystem;
-
-///
-/// Factory for abstracting creation of .
-///
-public interface ITimerFactory : ITimeSystemEntity
-{
-#if FEATURE_TIMER_COUNT
- ///
- long ActiveCount { get; }
-#endif
-
- ///
- ITimer New(TimerCallback callback);
-
- ///
- ITimer New(TimerCallback callback, object? state, int dueTime, int period);
-
- ///
- ITimer New(TimerCallback callback, object? state, long dueTime, long period);
-
- ///
- ITimer New(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period);
-
- ///
- /// Wraps the to the testable .
- ///
- ITimer Wrap(Timer timer);
-}
diff --git a/Source/Testably.Abstractions.Testing/Helpers/ExceptionFactory.cs b/Source/Testably.Abstractions.Testing/Helpers/ExceptionFactory.cs
index de20fd546..0eea2925c 100644
--- a/Source/Testably.Abstractions.Testing/Helpers/ExceptionFactory.cs
+++ b/Source/Testably.Abstractions.Testing/Helpers/ExceptionFactory.cs
@@ -19,9 +19,6 @@ public static NotSupportedException NotSupportedSafeFileHandle()
=> new(
"You cannot mock a safe file handle in the mocked file system without registering a strategy explicitly. Use `MockFileSystem.WithSafeFileHandleStrategy`!");
- public static NotSupportedException NotSupportedTimerWrapping()
- => new("You cannot wrap an existing Timer in the MockTimeSystem instance!");
-
public static ArgumentException SearchPatternCannotContainTwoDots()
=> new(
"Search pattern cannot contain \"..\" to move up directories and can be contained only internally in file/directory names, as in \"a..b\".");
@@ -241,15 +238,6 @@ internal static PlatformNotSupportedException UnixFileModeNotSupportedOnThisPlat
{
#if FEATURE_EXCEPTION_HRESULT
HResult = -2146233031
-#endif
- };
-
- public static ArgumentOutOfRangeException TimerArgumentOutOfRange(string propertyName)
- => new(propertyName,
- "Number must be either non-negative and less than or equal to Int32.MaxValue or -1")
- {
-#if FEATURE_EXCEPTION_HRESULT
- HResult = -2146233086
#endif
};
}
diff --git a/Source/Testably.Abstractions.Testing/MockTimeSystem.cs b/Source/Testably.Abstractions.Testing/MockTimeSystem.cs
index 9ca89bebc..347942218 100644
--- a/Source/Testably.Abstractions.Testing/MockTimeSystem.cs
+++ b/Source/Testably.Abstractions.Testing/MockTimeSystem.cs
@@ -22,16 +22,10 @@ public INotificationHandler On
///
public ITimeProvider TimeProvider { get; }
- ///
- /// The handler for mocked timers.
- ///
- public ITimerHandler TimerHandler => _timerMock;
-
private readonly NotificationHandler _callbackHandler;
private readonly DateTimeMock _dateTimeMock;
private readonly TaskMock _taskMock;
private readonly ThreadMock _threadMock;
- private readonly TimerFactoryMock _timerMock;
///
/// Initializes the with a random time.
@@ -57,7 +51,6 @@ public MockTimeSystem(ITimeProvider timeProvider)
_dateTimeMock = new DateTimeMock(this, _callbackHandler);
_threadMock = new ThreadMock(this, _callbackHandler);
_taskMock = new TaskMock(this, _callbackHandler);
- _timerMock = new TimerFactoryMock(this, _callbackHandler);
}
#region ITimeSystem Members
@@ -74,19 +67,5 @@ public ITask Task
public IThread Thread
=> _threadMock;
- ///
- public ITimerFactory Timer
- => _timerMock;
-
#endregion
-
- ///
- /// Specifies the to use when dealing with timers.
- ///
- /// The timer strategy.
- public MockTimeSystem WithTimerStrategy(ITimerStrategy timerStrategy)
- {
- _timerMock.SetTimerStrategy(timerStrategy);
- return this;
- }
}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/INotificationHandler.cs b/Source/Testably.Abstractions.Testing/TimeSystem/INotificationHandler.cs
index 7ad35f14b..df9a1abd1 100644
--- a/Source/Testably.Abstractions.Testing/TimeSystem/INotificationHandler.cs
+++ b/Source/Testably.Abstractions.Testing/TimeSystem/INotificationHandler.cs
@@ -56,17 +56,4 @@ Notification.IAwaitableCallback TaskDelay(
Notification.IAwaitableCallback ThreadSleep(
Action? callback = null,
Func? predicate = null);
-
- ///
- /// Callback executed when a timer callback was executed.
- ///
- /// The callback to execute after the Thread.Sleep was called.
- ///
- /// (optional) A predicate used to filter which callbacks should be notified.
- /// If set to (default value) all callbacks are notified.
- ///
- /// An to un-register the callback on dispose.
- Notification.IAwaitableCallback TimerExecuted(
- Action? callback = null,
- Func? predicate = null);
}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/ITimerHandler.cs b/Source/Testably.Abstractions.Testing/TimeSystem/ITimerHandler.cs
deleted file mode 100644
index 92a33d66a..000000000
--- a/Source/Testably.Abstractions.Testing/TimeSystem/ITimerHandler.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Testably.Abstractions.Testing.TimeSystem;
-
-///
-/// The timer handler gives access to all registered timers.
-///
-public interface ITimerHandler
-{
- ///
- /// Gets the timer associated with the specified .
- ///
- /// A zero-based incremented integer according to the order of the timer registration.
- ITimerMock this[int index] { get; }
-}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/ITimerMock.cs b/Source/Testably.Abstractions.Testing/TimeSystem/ITimerMock.cs
deleted file mode 100644
index 051ac3d77..000000000
--- a/Source/Testably.Abstractions.Testing/TimeSystem/ITimerMock.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-using Testably.Abstractions.TimeSystem;
-
-namespace Testably.Abstractions.Testing.TimeSystem;
-
-///
-/// Additional abstractions for a mocked timer to simplify testing.
-/// Implements .
-///
-public interface ITimerMock : ITimer
-{
- ///
- /// Blocks the current thread, until the timer is executed times.
- /// Throws an
- ///
- /// The number of execution cycles the thread is blocked.
- ///
- /// The timeout for blocking the current thread.
- /// Throws an when the timeout is expired.
- ///
- ///
- /// A callback to execute after the execution count, before the next execution is triggered.
- ///
- /// The method parameter allows stopping the timer by calling .
- ///
- ///
- ///
- /// When the expires before the timer is executed
- /// times.
- ///
- ITimerMock Wait(int executionCount = 1, int timeout = 10000,
- Action? callback = null);
-}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/ITimerStrategy.cs b/Source/Testably.Abstractions.Testing/TimeSystem/ITimerStrategy.cs
deleted file mode 100644
index 6ead4badc..000000000
--- a/Source/Testably.Abstractions.Testing/TimeSystem/ITimerStrategy.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System.Threading;
-
-namespace Testably.Abstractions.Testing.TimeSystem;
-
-///
-/// The strategy how to handle mocked timers for testing.
-///
-public interface ITimerStrategy
-{
- ///
- /// The timer mode.
- ///
- TimerMode Mode { get; }
-
- ///
- /// Flag indicating, if exceptions in the should be swallowed or thrown.
- ///
- /// The real will crash the application in case of an exception in the
- /// .
- ///
- bool SwallowExceptions { get; }
-}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/NotificationHandler.cs b/Source/Testably.Abstractions.Testing/TimeSystem/NotificationHandler.cs
index 5c64c4aa6..2a363fe30 100644
--- a/Source/Testably.Abstractions.Testing/TimeSystem/NotificationHandler.cs
+++ b/Source/Testably.Abstractions.Testing/TimeSystem/NotificationHandler.cs
@@ -13,9 +13,6 @@ private readonly Notification.INotificationFactory
private readonly Notification.INotificationFactory
_threadSleepCallbacks = Notification.CreateFactory();
- private readonly Notification.INotificationFactory
- _timerExecutedCallbacks = Notification.CreateFactory();
-
#region INotificationHandler Members
///
@@ -36,12 +33,6 @@ public Notification.IAwaitableCallback ThreadSleep(
Func? predicate = null)
=> _threadSleepCallbacks.RegisterCallback(callback, predicate);
- ///
- public Notification.IAwaitableCallback TimerExecuted(
- Action? callback = null,
- Func? predicate = null)
- => _timerExecutedCallbacks.RegisterCallback(callback, predicate);
-
#endregion
public void InvokeDateTimeReadCallbacks(DateTime now)
@@ -52,7 +43,4 @@ public void InvokeTaskDelayCallbacks(TimeSpan delay)
public void InvokeThreadSleepCallbacks(TimeSpan timeout)
=> _threadSleepCallbacks.InvokeCallbacks(timeout);
-
- public void InvokeTimerExecutedCallbacks(TimerExecution timerExecution)
- => _timerExecutedCallbacks.InvokeCallbacks(timerExecution);
}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/TimerExecution.cs b/Source/Testably.Abstractions.Testing/TimeSystem/TimerExecution.cs
deleted file mode 100644
index bc4513097..000000000
--- a/Source/Testably.Abstractions.Testing/TimeSystem/TimerExecution.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-
-namespace Testably.Abstractions.Testing.TimeSystem;
-
-///
-/// A container for notifying the execution of a timer callback.
-///
-public class TimerExecution
-{
- ///
- /// The time when the callback finished executing.
- ///
- public DateTime Time { get; }
-
- ///
- /// The (zero-based) execution counter.
- ///
- public int ExecutionCount { get; }
-
- ///
- /// The mocked timer.
- ///
- public ITimerMock Timer { get; }
-
- ///
- /// The exception thrown during this timer execution.
- ///
- public Exception? Exception { get; }
-
- internal TimerExecution(DateTime time, int executionCount, ITimerMock timer,
- Exception? exception)
- {
- Time = time;
- ExecutionCount = executionCount;
- Timer = timer;
- Exception = exception;
- }
-}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/TimerFactoryMock.cs b/Source/Testably.Abstractions.Testing/TimeSystem/TimerFactoryMock.cs
deleted file mode 100644
index 54b067cd6..000000000
--- a/Source/Testably.Abstractions.Testing/TimeSystem/TimerFactoryMock.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-using System;
-using System.Collections.Concurrent;
-using System.IO;
-using System.Threading;
-using Testably.Abstractions.Testing.Helpers;
-using Testably.Abstractions.TimeSystem;
-
-namespace Testably.Abstractions.Testing.TimeSystem;
-
-internal sealed class TimerFactoryMock : ITimerFactory, ITimerHandler
-{
- private readonly NotificationHandler _callbackHandler;
- private readonly MockTimeSystem _mockTimeSystem;
- private ITimerStrategy _timerStrategy;
- private readonly ConcurrentDictionary _timers = new();
- private int _nextIndex = -1;
-
- internal TimerFactoryMock(MockTimeSystem timeSystem,
- NotificationHandler callbackHandler)
- {
- _mockTimeSystem = timeSystem;
- _callbackHandler = callbackHandler;
- _timerStrategy = TimerStrategy.Default;
- }
-
- #region ITimerFactory Members
-
- ///
- public ITimeSystem TimeSystem
- => _mockTimeSystem;
-
- #endregion
-
-#if FEATURE_TIMER_COUNT
- ///
- public long ActiveCount => _timers.Count;
-#endif
-
- ///
- public ITimer New(TimerCallback callback)
- {
- TimerMock timerMock = new(_mockTimeSystem, _callbackHandler, _timerStrategy,
- callback, null, Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
- return RegisterTimerMock(timerMock);
- }
-
- ///
- public ITimer New(TimerCallback callback, object? state, int dueTime, int period)
- {
- TimerMock timerMock = new(_mockTimeSystem, _callbackHandler, _timerStrategy,
- callback, state, TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period));
- return RegisterTimerMock(timerMock);
- }
-
- ///
- public ITimer New(TimerCallback callback, object? state, long dueTime, long period)
- {
- TimerMock timerMock = new(_mockTimeSystem, _callbackHandler, _timerStrategy,
- callback, state, TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period));
- return RegisterTimerMock(timerMock);
- }
-
- ///
- public ITimer New(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period)
- {
- TimerMock timerMock = new(_mockTimeSystem, _callbackHandler, _timerStrategy,
- callback, state, dueTime, period);
- return RegisterTimerMock(timerMock);
- }
-
- ///
- public ITimer Wrap(Timer timer)
- => throw ExceptionFactory.NotSupportedTimerWrapping();
-
- private TimerMock RegisterTimerMock(TimerMock timerMock)
- {
- int index = Interlocked.Increment(ref _nextIndex);
- if (_timers.TryAdd(index, timerMock))
- {
- timerMock.RegisterOnDispose(() => _timers.TryRemove(index, out _));
- }
-
- return timerMock;
- }
-
- internal ITimerHandler SetTimerStrategy(ITimerStrategy timerStrategy)
- {
- _timerStrategy = timerStrategy;
- return this;
- }
-
- ///
- public ITimerMock this[int index]
- => _timers[index];
-}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/TimerMock.cs b/Source/Testably.Abstractions.Testing/TimeSystem/TimerMock.cs
deleted file mode 100644
index 928fb929c..000000000
--- a/Source/Testably.Abstractions.Testing/TimeSystem/TimerMock.cs
+++ /dev/null
@@ -1,329 +0,0 @@
-using System;
-using System.Threading;
-using Testably.Abstractions.Testing.Helpers;
-using Testably.Abstractions.TimeSystem;
-#if FEATURE_ASYNC_DISPOSABLE
-using System.Threading.Tasks;
-#endif
-
-namespace Testably.Abstractions.Testing.TimeSystem;
-
-internal sealed class TimerMock : ITimerMock
-{
- private readonly TimerCallback _callback;
- private readonly NotificationHandler _callbackHandler;
- private CancellationTokenSource? _cancellationTokenSource;
- private readonly ManualResetEventSlim _continueEvent = new();
- private CountdownEvent? _countdownEvent;
- private TimeSpan _dueTime;
- private Exception? _exception;
- private int _executionCount;
- private bool _isDisposed;
- private readonly object _lock = new();
- private readonly MockTimeSystem _mockTimeSystem;
- private Action? _onDispose;
- private TimeSpan _period;
- private readonly object? _state;
- private readonly ITimerStrategy _timerStrategy;
-
- internal TimerMock(MockTimeSystem timeSystem,
- NotificationHandler callbackHandler,
- ITimerStrategy timerStrategy,
- TimerCallback callback,
- object? state,
- TimeSpan dueTime,
- TimeSpan period)
- {
- if (dueTime.TotalMilliseconds < -1)
- {
- throw ExceptionFactory.TimerArgumentOutOfRange(nameof(dueTime));
- }
-
- if (period.TotalMilliseconds < -1)
- {
- throw new ArgumentOutOfRangeException(nameof(period));
- }
-
- _mockTimeSystem = timeSystem;
- _callbackHandler = callbackHandler;
- _timerStrategy = timerStrategy;
- _callback = callback;
- _state = state;
- _dueTime = dueTime;
- _period = period;
- if (_timerStrategy.Mode == TimerMode.StartImmediately)
- {
- Start();
- }
- }
-
- #region ITimerMock Members
-
- ///
- public ITimeSystem TimeSystem
- => _mockTimeSystem;
-
-#if FEATURE_ASYNC_DISPOSABLE
- ///
- public ValueTask DisposeAsync()
- {
- Dispose();
-#if NETSTANDARD2_1
- return new ValueTask();
-#else
- return ValueTask.CompletedTask;
-#endif
- }
-#endif
-
- ///
- public void Dispose()
- {
- if (!_isDisposed)
- {
- _isDisposed = true;
- Stop();
- _onDispose?.Invoke();
- lock (_lock)
- {
- _cancellationTokenSource?.Dispose();
- _cancellationTokenSource = null;
- }
- }
- }
-
- ///
- public bool Change(int dueTime, int period)
- => Change(TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period));
-
- ///
- public bool Change(long dueTime, long period)
- => Change(TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMilliseconds(period));
-
- ///
- public bool Change(TimeSpan dueTime, TimeSpan period)
- {
- if (_isDisposed)
- {
- throw new ObjectDisposedException("Cannot access a disposed object.");
- }
-
- if (dueTime.TotalMilliseconds < -1)
- {
- throw ExceptionFactory.TimerArgumentOutOfRange(nameof(dueTime));
- }
-
- if (period.TotalMilliseconds < -1)
- {
- throw new ArgumentOutOfRangeException(nameof(period));
- }
-
- try
- {
- Stop();
- _dueTime = dueTime;
- _period = period;
- Start();
- return true;
- }
- catch (Exception)
- {
- return false;
- }
- }
-
- ///
- public bool Dispose(WaitHandle notifyObject)
- {
- if (_isDisposed)
- {
- return false;
- }
-
- switch (notifyObject)
- {
- case Mutex m:
- m.WaitOne();
- Dispose();
- m.ReleaseMutex();
- break;
- case Semaphore s:
- s.WaitOne();
- Dispose();
- s.Release();
- break;
- case EventWaitHandle e:
- Dispose();
- e.Set();
- break;
- default:
- throw new NotSupportedException("The wait handle is not of any supported type!");
- }
-
- return true;
- }
-
- ///
- public ITimerMock Wait(
- int executionCount = 1,
- int timeout = 10000,
- Action? callback = null)
- {
- if (executionCount <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(executionCount));
- }
-
- if (timeout < -1)
- {
- throw new ArgumentOutOfRangeException(nameof(timeout));
- }
-
- if (_timerStrategy.Mode != TimerMode.StartImmediately)
- {
- Start();
- }
-
- try
- {
- _countdownEvent = new CountdownEvent(executionCount - _executionCount);
- if (!_countdownEvent.Wait(timeout))
- {
- throw new TimeoutException(
- $"The execution count {executionCount} was not reached in {timeout}ms.");
- }
- }
- catch (ArgumentOutOfRangeException)
- {
- // In case of an ArgumentOutOfRangeException, the executionCount is already reached.
- }
-
- if (_exception != null)
- {
- throw _exception;
- }
-
- callback?.Invoke(this);
- _continueEvent.Set();
-
- return this;
- }
-
- #endregion
-
- internal void RegisterOnDispose(Action? onDispose)
- {
- _onDispose = onDispose;
- }
-
- private void RunTimer(CancellationToken cancellationToken = default)
- {
- _mockTimeSystem.Thread.Sleep(_dueTime);
- if (_dueTime.TotalMilliseconds < 0)
- {
- cancellationToken.WaitHandle.WaitOne(_dueTime);
- }
-
- Thread.Yield();
- DateTime nextPlannedExecution = _mockTimeSystem.DateTime.UtcNow;
- while (!cancellationToken.IsCancellationRequested)
- {
- nextPlannedExecution += _period;
- Exception? exception = null;
- try
- {
- _callback(_state);
- }
- catch (Exception swallowedException)
- {
- _exception = exception = swallowedException;
- }
-
- _callbackHandler.InvokeTimerExecutedCallbacks(
- new TimerExecution(
- _mockTimeSystem.DateTime.UtcNow,
- _executionCount,
- this,
- exception));
- _executionCount++;
- if (_countdownEvent?.Signal() == true)
- {
- _continueEvent.Wait(cancellationToken);
- _continueEvent.Reset();
- }
-
- if (_exception != null && !_timerStrategy.SwallowExceptions)
- {
- break;
- }
-
- if (_period.TotalMilliseconds <= 0 ||
- cancellationToken.IsCancellationRequested)
- {
- return;
- }
-
- TimeSpan delay = nextPlannedExecution - _mockTimeSystem.DateTime.UtcNow;
- if (delay > TimeSpan.Zero)
- {
- _mockTimeSystem.Thread.Sleep(delay);
- }
-
- Thread.Yield();
- }
- }
-
- private void Start()
- {
- Stop();
- CancellationTokenSource runningCancellationTokenSource;
- lock (_lock)
- {
- _cancellationTokenSource = new CancellationTokenSource();
- runningCancellationTokenSource = _cancellationTokenSource;
- }
-
- CancellationToken token = runningCancellationTokenSource.Token;
- ManualResetEventSlim startCreateTimerThreads = new();
- Thread t = new(() =>
- {
- try
- {
- startCreateTimerThreads.Set();
- RunTimer(token);
- }
- catch (Exception ex)
- {
- _exception = ex;
- }
- finally
- {
- runningCancellationTokenSource.Dispose();
- lock (_lock)
- {
- if (_cancellationTokenSource == runningCancellationTokenSource)
- {
- _cancellationTokenSource.Dispose();
- _cancellationTokenSource = null;
- }
- }
- }
- })
- {
- IsBackground = true
- };
- t.Start();
- startCreateTimerThreads.Wait(token);
- }
-
- private void Stop()
- {
- lock (_lock)
- {
- if (_cancellationTokenSource is { IsCancellationRequested: false })
- {
- _cancellationTokenSource?.Cancel();
- }
- }
- }
-}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/TimerMode.cs b/Source/Testably.Abstractions.Testing/TimeSystem/TimerMode.cs
deleted file mode 100644
index 349d13bb8..000000000
--- a/Source/Testably.Abstractions.Testing/TimeSystem/TimerMode.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace Testably.Abstractions.Testing.TimeSystem;
-
-///
-/// The timer mode.
-///
-public enum TimerMode
-{
- ///
- /// Start the timer thread immediately.
- ///
- /// This is the normal behaviour of real s.
- ///
- StartImmediately = 1,
-
- ///
- /// Wait execution of timers until a is called.
- ///
- /// This simplifies certain test cases.
- ///
- StartOnMockWait = 2,
-}
diff --git a/Source/Testably.Abstractions.Testing/TimeSystem/TimerStrategy.cs b/Source/Testably.Abstractions.Testing/TimeSystem/TimerStrategy.cs
deleted file mode 100644
index 4af50d0c9..000000000
--- a/Source/Testably.Abstractions.Testing/TimeSystem/TimerStrategy.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-namespace Testably.Abstractions.Testing.TimeSystem;
-
-///
-/// The timer strategy.
-///
-public class TimerStrategy : ITimerStrategy
-{
- ///
- /// The default time strategy uses .
- ///
- public static ITimerStrategy Default { get; }
- = new TimerStrategy(TimerMode.StartImmediately);
-
- ///
- public TimerMode Mode { get; }
-
- ///
- public bool SwallowExceptions { get; }
-
- ///
- /// Initializes a new instance of .
- ///
- /// The timer mode.
- /// Flag, indicating if exceptions should be swallowed.
- public TimerStrategy(
- TimerMode mode = TimerMode.StartImmediately,
- bool swallowExceptions = false)
- {
- Mode = mode;
- SwallowExceptions = swallowExceptions;
- }
-}
diff --git a/Source/Testably.Abstractions/RealTimeSystem.cs b/Source/Testably.Abstractions/RealTimeSystem.cs
index f6f288986..c2b752574 100644
--- a/Source/Testably.Abstractions/RealTimeSystem.cs
+++ b/Source/Testably.Abstractions/RealTimeSystem.cs
@@ -23,9 +23,5 @@ public ITask Task
public IThread Thread
=> new ThreadWrapper(this);
- ///
- public ITimerFactory Timer
- => new TimerFactory(this);
-
#endregion
}
diff --git a/Source/Testably.Abstractions/TimeSystem/TimerFactory.cs b/Source/Testably.Abstractions/TimeSystem/TimerFactory.cs
deleted file mode 100644
index 9f2708fa6..000000000
--- a/Source/Testably.Abstractions/TimeSystem/TimerFactory.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.IO;
-using System.Threading;
-
-namespace Testably.Abstractions.TimeSystem;
-
-internal sealed class TimerFactory : ITimerFactory
-{
- internal TimerFactory(RealTimeSystem timeSystem)
- {
- TimeSystem = timeSystem;
- }
-
- ///
- public ITimeSystem TimeSystem { get; }
-
-#if FEATURE_TIMER_COUNT
- ///
- public long ActiveCount => Timer.ActiveCount;
-#endif
-
- ///
- public ITimer New(TimerCallback callback)
- => Wrap(new Timer(callback));
-
- ///
- public ITimer New(TimerCallback callback, object? state, int dueTime, int period)
- => Wrap(new Timer(callback, state, dueTime, period));
-
- ///
- public ITimer New(TimerCallback callback, object? state, long dueTime, long period)
- => Wrap(new Timer(callback, state, dueTime, period));
-
- ///
- public ITimer New(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period)
- => Wrap(new Timer(callback, state, dueTime, period));
-
- ///
- public ITimer Wrap(Timer timer)
- => new TimerWrapper(TimeSystem, timer);
-}
diff --git a/Source/Testably.Abstractions/TimeSystem/TimerWrapper.cs b/Source/Testably.Abstractions/TimeSystem/TimerWrapper.cs
deleted file mode 100644
index fc2234e5c..000000000
--- a/Source/Testably.Abstractions/TimeSystem/TimerWrapper.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Testably.Abstractions.TimeSystem;
-
-internal sealed class TimerWrapper : ITimer
-{
- private readonly Timer _timer;
-
- internal TimerWrapper(ITimeSystem timeSystem, Timer timer)
- {
- TimeSystem = timeSystem;
- _timer = timer;
- }
-
- #region ITimer Members
-
- ///
- public ITimeSystem TimeSystem { get; }
-
- ///
- public bool Change(int dueTime, int period)
- => _timer.Change(dueTime, period);
-
- ///
- public bool Change(long dueTime, long period)
- => _timer.Change(dueTime, period);
-
- ///
- public bool Change(TimeSpan dueTime, TimeSpan period)
- => _timer.Change(dueTime, period);
-
- ///
- public bool Dispose(WaitHandle notifyObject)
- => _timer.Dispose(notifyObject);
-
- ///
- public void Dispose()
- => _timer.Dispose();
-
-#if FEATURE_ASYNC_DISPOSABLE
- ///
- public ValueTask DisposeAsync()
- => _timer.DisposeAsync();
-#endif
-
- #endregion
-}
diff --git a/Testably.Abstractions.v3.ncrunchsolution b/Testably.Abstractions.v3.ncrunchsolution
deleted file mode 100644
index 420dc0202..000000000
--- a/Testably.Abstractions.v3.ncrunchsolution
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- True
-
- Source\Testably.Abstractions.Testing\Testably.Abstractions.Testing.csproj:netstandard2.1
- Source\Testably.Abstractions.Testing\Testably.Abstractions.Testing.csproj:netstandard2.0
- Source\Testably.Abstractions\Testably.Abstractions.csproj:netstandard2.1
- Source\Testably.Abstractions\Testably.Abstractions.csproj:netstandard2.0
- Tests\Testably.Abstractions.Tests\Testably.Abstractions.Tests.csproj
- Source\Testably.Abstractions.Extensions\Testably.Abstractions.Extensions.csproj:netstandard2.0
- Source\Testably.Abstractions.Extensions\Testably.Abstractions.Extensions.csproj:netstandard2.1
- Tests\Testably.Abstractions.Extensions.Tests\Testably.Abstractions.Extensions.Tests.csproj
-
- True
-
-
\ No newline at end of file
diff --git a/Tests/Helpers/Testably.Abstractions.TestHelpers/Test.cs b/Tests/Helpers/Testably.Abstractions.TestHelpers/Test.cs
index fe2548f71..33cf0a2ab 100644
--- a/Tests/Helpers/Testably.Abstractions.TestHelpers/Test.cs
+++ b/Tests/Helpers/Testably.Abstractions.TestHelpers/Test.cs
@@ -41,13 +41,6 @@ public static void SkipBrittleTestsOnRealFileSystem(
"Brittle tests are skipped on the real file system.");
}
- public static void SkipBrittleTestsOnRealTimeSystem(
- ITimeSystem timeSystem, bool condition = true)
- {
- Skip.If(timeSystem is RealTimeSystem && condition,
- "Brittle tests are skipped on the real time system.");
- }
-
public static void SkipIfLongRunningTestsShouldBeSkipped(IFileSystem fileSystem)
{
#if DEBUG && !INCLUDE_LONGRUNNING_TESTS_ALSO_IN_DEBUG_MODE
diff --git a/Tests/Testably.Abstractions.Parity.Tests/ParityTests.cs b/Tests/Testably.Abstractions.Parity.Tests/ParityTests.cs
index 3fc6c4f60..2cc08a268 100644
--- a/Tests/Testably.Abstractions.Parity.Tests/ParityTests.cs
+++ b/Tests/Testably.Abstractions.Parity.Tests/ParityTests.cs
@@ -136,18 +136,6 @@ public void IRandomAndIRandomFactory_EnsureParityWith_Random()
parityErrors.Should().BeEmpty();
}
- [Fact]
- public void
- ITimerAndITimerFactory_EnsureParityWith_Timer()
- {
- List parityErrors = Parity.Timer
- .GetErrorsToInstanceType(
- typeof(Timer),
- _testOutputHelper);
-
- parityErrors.Should().BeEmpty();
- }
-
[Fact]
public void IZipArchive_EnsureParityWith_ZipArchive()
{
diff --git a/Tests/Testably.Abstractions.Parity.Tests/TestHelpers/Parity.cs b/Tests/Testably.Abstractions.Parity.Tests/TestHelpers/Parity.cs
index 5237a44df..014bd789e 100644
--- a/Tests/Testably.Abstractions.Parity.Tests/TestHelpers/Parity.cs
+++ b/Tests/Testably.Abstractions.Parity.Tests/TestHelpers/Parity.cs
@@ -2,7 +2,6 @@
using System.Collections.ObjectModel;
using System.IO;
using System.IO.Compression;
-using System.Threading;
namespace Testably.Abstractions.Parity.Tests.TestHelpers;
@@ -63,25 +62,6 @@ public class Parity
});
public ParityCheck Random { get; } = new();
-
- public ParityCheck Timer { get; } = new(excludeMethods: new[]
- {
- typeof(Timer).GetMethod(nameof(System.Threading.Timer.Change), new[]
- {
- typeof(uint),
- typeof(uint)
- })
- }, excludeConstructors: new[]
- {
- typeof(Timer).GetConstructor(new[]
- {
- typeof(TimerCallback),
- typeof(object),
- typeof(uint),
- typeof(uint)
- })
- });
-
public ParityCheck ZipArchive { get; } = new();
public ParityCheck ZipArchiveEntry { get; } = new(excludeMethods: new[]
diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileSystemWatcherMockTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileSystemWatcherMockTests.cs
index a324513ed..ab61f07ff 100644
--- a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileSystemWatcherMockTests.cs
+++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/FileSystemWatcherMockTests.cs
@@ -1,7 +1,6 @@
using System.IO;
using System.Threading;
using Testably.Abstractions.Testing.FileSystemInitializer;
-using Testably.Abstractions.Testing.Tests.TestHelpers;
namespace Testably.Abstractions.Testing.Tests.FileSystem;
@@ -38,8 +37,6 @@ public void Dispose()
public void Error_DefaultTo64Messages_ShouldBeTriggeredWhenBufferOverflows(
string path)
{
- Skip.If(Test.RunsOnWindows, "Brittle test under Windows on GitHub");
-
FileSystem.Directory.CreateDirectory(path);
IFileSystemWatcher fileSystemWatcher =
FileSystem.FileSystemWatcher.New(BasePath);
@@ -80,8 +77,6 @@ public void Error_DefaultTo64Messages_ShouldBeTriggeredWhenBufferOverflows(
public void Error_ShouldBeTriggeredWhenBufferOverflows(
int internalBufferSize, string path)
{
- Skip.If(Test.RunsOnWindows, "Brittle test under Windows on GitHub");
-
int maxMessages = internalBufferSize / 128;
FileSystem.Directory.CreateDirectory(path);
IFileSystemWatcher fileSystemWatcher =
@@ -112,7 +107,7 @@ public void Error_ShouldBeTriggeredWhenBufferOverflows(
FileSystem.Directory.CreateDirectory($"{i}_{path}");
}
- block2.Wait(10000).Should().BeTrue();
+ block2.Wait(5000).Should().BeTrue();
fileSystemWatcher.Dispose();
result.Should().NotBeNull();
result!.GetException().Should().BeOfType();
diff --git a/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/NotificationHandlerTests.cs b/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/NotificationHandlerTests.cs
index 098a338b1..4e09b0b04 100644
--- a/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/NotificationHandlerTests.cs
+++ b/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/NotificationHandlerTests.cs
@@ -1,6 +1,5 @@
using System.Threading;
using Testably.Abstractions.Testing.Tests.TestHelpers;
-using Testably.Abstractions.Testing.TimeSystem;
namespace Testably.Abstractions.Testing.Tests.TimeSystem;
@@ -298,109 +297,4 @@ public void
receivedTimeout.Should().Be(expectedTimeout);
}
-
- [Fact]
- public void
- OnTimerExecuted_DisposedCallback_ShouldNotBeCalled()
- {
- MockTimeSystem timeSystem = new();
- ITimerHandler timerHandler = timeSystem.TimerHandler;
- TimerExecution? receivedValue = null;
- IDisposable disposable = timeSystem.On.TimerExecuted(d => receivedValue = d);
-
- disposable.Dispose();
- timeSystem.Timer.New(_ => { }, null,
- TimeTestHelper.GetRandomInterval(),
- TimeTestHelper.GetRandomInterval());
-
- timerHandler[0].Wait();
- receivedValue.Should().BeNull();
- }
-
- [Fact]
- public void
- OnTimerExecuted_MultipleCallbacks_DisposeOne_ShouldCallOtherCallbacks()
- {
- MockTimeSystem timeSystem = new();
- ITimerHandler timerHandler = timeSystem.TimerHandler;
- TimerExecution? receivedTimeout1 = null;
- TimerExecution? receivedTimeout2 = null;
-
- using (timeSystem.On.TimerExecuted(d => receivedTimeout1 = d))
- {
- timeSystem.On.TimerExecuted(d => receivedTimeout2 = d).Dispose();
- timeSystem.Timer.New(_ => { }, null,
- TimeTestHelper.GetRandomInterval(),
- TimeTestHelper.GetRandomInterval());
- timerHandler[0].Wait();
- }
-
- receivedTimeout1.Should().NotBeNull();
- receivedTimeout2.Should().BeNull();
- }
-
- [Fact]
- public void
- OnTimerExecuted_MultipleCallbacks_ShouldAllBeCalled()
- {
- MockTimeSystem timeSystem = new();
- ITimerHandler timerHandler = timeSystem.TimerHandler;
- TimerExecution? receivedTimeout1 = null;
- TimerExecution? receivedTimeout2 = null;
-
- using (timeSystem.On.TimerExecuted(d => receivedTimeout1 = d))
- {
- using (timeSystem.On.TimerExecuted(d => receivedTimeout2 = d))
- {
- timeSystem.Timer.New(_ => { }, null,
- TimeTestHelper.GetRandomInterval(),
- TimeTestHelper.GetRandomInterval());
- timerHandler[0].Wait();
- }
- }
-
- receivedTimeout1.Should().NotBeNull();
- receivedTimeout2.Should().NotBeNull();
- }
-
- [Fact]
- public void
- OnTimerExecuted_WithMilliseconds_ShouldExecuteCallbackWithCorrectParameter()
- {
- int millisecondsTimeout = new Random().Next();
- MockTimeSystem timeSystem = new MockTimeSystem()
- .WithTimerStrategy(new TimerStrategy(TimerMode.StartOnMockWait));
- ITimerHandler timerHandler = timeSystem.TimerHandler;
- TimerExecution? receivedValue = null;
- DateTime now = timeSystem.DateTime.UtcNow;
-
- using (timeSystem.On.TimerExecuted(d => receivedValue = d))
- {
- timeSystem.Timer.New(_ => { }, null, millisecondsTimeout, 0);
- timerHandler[0].Wait();
- }
-
- TimeSpan difference = receivedValue!.Time - now;
- difference.Should().Be(TimeSpan.FromMilliseconds(millisecondsTimeout));
- }
-
- [Fact]
- public void
- OnTimerExecuted_WithTimeSpan_ShouldExecuteCallbackWithCorrectParameter()
- {
- TimeSpan expectedTimeout = TimeTestHelper.GetRandomInterval();
- MockTimeSystem timeSystem = new();
- ITimerHandler timerHandler = timeSystem.TimerHandler;
- TimerExecution? receivedValue = null;
- DateTime now = timeSystem.DateTime.UtcNow;
-
- using (timeSystem.On.TimerExecuted(d => receivedValue = d))
- {
- timeSystem.Timer.New(_ => { }, null, expectedTimeout, TimeSpan.Zero);
- timerHandler[0].Wait();
- }
-
- TimeSpan difference = receivedValue!.Time - now;
- difference.Should().Be(expectedTimeout);
- }
}
diff --git a/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimeSystemExtensibilityTests.cs b/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimeSystemExtensibilityTests.cs
index fac432cd9..fcac27bd4 100644
--- a/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimeSystemExtensibilityTests.cs
+++ b/Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimeSystemExtensibilityTests.cs
@@ -31,15 +31,6 @@ public void Thread_ShouldSetExtensionPoint(ITimeSystem timeSystem)
result.Should().Be(timeSystem);
}
- [SkippableTheory]
- [MemberData(nameof(GetTimeSystems))]
- public void Timer_ShouldSetExtensionPoint(ITimeSystem timeSystem)
- {
- ITimeSystem result = timeSystem.Timer.TimeSystem;
-
- result.Should().Be(timeSystem);
- }
-
public static IEnumerable