Skip to content

fix: correctly handle missing auto-advance in ITimer#990

Merged
vbreuss merged 3 commits intomainfrom
topic/timer-changes
Apr 10, 2026
Merged

fix: correctly handle missing auto-advance in ITimer#990
vbreuss merged 3 commits intomainfrom
topic/timer-changes

Conversation

@vbreuss
Copy link
Copy Markdown
Member

@vbreuss vbreuss commented Apr 9, 2026

Fixes mocked ITimer behavior in MockTimeSystem so that, when auto-advancing time is disabled, timer callbacks are not invoked until the mocked time is explicitly advanced—bringing timer behavior in line with the rest of the time system abstractions.

Changes:

  • Thread auto-advance configuration into TimerFactoryMock/TimerMock and update timer scheduling accordingly.
  • Update TimerMock execution loop to wait based on planned execution ticks instead of always delaying via mocked Task.Delay.
  • Add/adjust tests covering DisableAutoAdvance timer behavior and correct a timer period in an existing time-change parity test.

@vbreuss vbreuss self-assigned this Apr 9, 2026
@vbreuss vbreuss added the bug Something isn't working label Apr 9, 2026
Copilot AI review requested due to automatic review settings April 9, 2026 19:53
@vbreuss vbreuss changed the title fix: mocked ITimer does not wait for time to advance before invoking callback fix: correctly handle auto-advance in ITimer Apr 9, 2026
@vbreuss vbreuss changed the title fix: correctly handle auto-advance in ITimer fix: correctly handle missing auto-advance in ITimer Apr 9, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes mocked ITimer behavior in MockTimeSystem so that, when auto-advancing time is disabled, timer callbacks are not invoked until the mocked time is explicitly advanced—bringing timer behavior in line with the rest of the time system abstractions.

Changes:

  • Thread auto-advance configuration into TimerFactoryMock/TimerMock and update timer scheduling accordingly.
  • Update TimerMock execution loop to wait based on planned execution ticks instead of always delaying via mocked Task.Delay.
  • Add/adjust tests covering DisableAutoAdvance timer behavior and correct a timer period in an existing time-change parity test.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
Tests/Testably.Abstractions.Testing.Tests/TimeSystem/TimerMockTests.cs Adds new tests for DisableAutoAdvance timer behavior; adjusts period in ShouldNotBeAffectedByTimeChange.
Source/Testably.Abstractions.Testing/TimeSystem/TimerMock.cs Implements non-auto-advance waiting via On.TimeChanged and planned execution ticks; adds _autoAdvance plumbing.
Source/Testably.Abstractions.Testing/TimeSystem/TimerFactoryMock.cs Propagates AutoAdvance into created TimerMock instances.
Source/Testably.Abstractions.Testing/MockTimeSystem.cs Passes initialization.AutoAdvance into TimerFactoryMock.

@vbreuss vbreuss force-pushed the topic/timer-changes branch from 031e11f to fcd9636 Compare April 9, 2026 20:06
@vbreuss vbreuss enabled auto-merge (squash) April 9, 2026 20:08
@github-actions
Copy link
Copy Markdown

Test Results

     62 files   -     40       62 suites   - 40   1h 38m 18s ⏱️ - 51m 45s
 73 362 tests  - 39 122   64 998 ✅  - 34 876   8 364 💤  -  4 246  0 ❌ ±0 
170 228 runs   - 98 170  144 896 ✅  - 86 814  25 332 💤  - 11 356  0 ❌ ±0 

Results for commit fcd9636. ± Comparison against base commit af46ef8.

This pull request removes 109805 and adds 70682 tests. Note that renamed tests count towards both.
  )
)
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ CreateDirectory_NullDirectorySecurity_ShouldThrowArgumentNullException
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ CreateDirectory_ShouldChangeAccessControl(bar)
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ CreateDirectory_ShouldChangeAccessControl(bar\foo)
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ GetAccessControl_ShouldBeInitializedWithNotNullValue
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ GetAccessControl_ShouldReturnSetResult
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ GetAccessControl_WithAccessControlSections_ShouldBeInitializedWithNotNullValue
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ GetAccessControl_WithAccessControlSections_ShouldReturnSetResult
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ SetAccessControl_ShouldChangeAccessControl
…
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(0897d7f7-ed92-4112-a8f6-484d1e867a61)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(094435b4-6168-47b7-923f-1b9f78c9847d)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(09c3e797-1a8b-4737-aa28-4f3fd0dd328e)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(0f966e45-279d-455a-9c83-1683815cbb9e)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(0fee27fd-e867-40bb-9394-958d208cc6c1)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(2118eb21-7b65-47d4-88ab-340b712c2654)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(2133b6ad-e8df-49b0-8df5-4ce1a283d6ba)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(23897a5a-90ee-4381-ba59-52e7ea609e74)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(25d7f6c1-7310-4589-957f-77883b2cf570)
Testably.Abstractions.Compression.Tests.ZipArchive.Tests ‑ Comment_ShouldBeSettable(27776ebf-7c3d-477a-b14f-7c5a259ac0d9)
…
This pull request removes 12569 skipped tests and adds 8292 skipped tests. Note that renamed tests count towards both.
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ GetAccessControl_WithAccessControlSections_ShouldBeInitializedWithNotNullValue
Testably.Abstractions.AccessControl.Tests.DirectoryAclExtensionsTests ‑ SetAccessControl_ShouldNotUpdateTimes
Testably.Abstractions.AccessControl.Tests.DirectoryInfoAclExtensionsTests ‑ GetAccessControl_WithAccessControlSections_ShouldBeInitializedWithNotNullValue
Testably.Abstractions.AccessControl.Tests.DirectoryInfoAclExtensionsTests ‑ SetAccessControl_ShouldNotUpdateTimes(0b55263c-03e3-401e-89b3-96f4c6ed4088)
Testably.Abstractions.AccessControl.Tests.DirectoryInfoAclExtensionsTests ‑ SetAccessControl_ShouldNotUpdateTimes(1f9e8d26-7dc4-4b2a-a335-dddd23971cfd)
Testably.Abstractions.AccessControl.Tests.DirectoryInfoAclExtensionsTests ‑ SetAccessControl_ShouldNotUpdateTimes(1fc62296-58e9-41d8-ad09-19653c222707)
Testably.Abstractions.AccessControl.Tests.DirectoryInfoAclExtensionsTests ‑ SetAccessControl_ShouldNotUpdateTimes(33f7e722-69b8-411b-8f89-b9d5a441afc9)
Testably.Abstractions.AccessControl.Tests.DirectoryInfoAclExtensionsTests ‑ SetAccessControl_ShouldNotUpdateTimes(3ab8b91c-2c5c-46a5-adab-a39272c40410)
Testably.Abstractions.AccessControl.Tests.DirectoryInfoAclExtensionsTests ‑ SetAccessControl_ShouldNotUpdateTimes(3e03f244-2c11-49a4-99d5-7c18b7356a9c)
Testably.Abstractions.AccessControl.Tests.DirectoryInfoAclExtensionsTests ‑ SetAccessControl_ShouldNotUpdateTimes(410e745e-1c32-4491-b332-31a20d6ab174)
…
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(0ea557fa-b8e6-4f26-bf27-35f11b05d282)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(100cd39c-68f2-411c-8dfb-e7fd0e9bd8c0)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(15742b2a-53d0-47ea-902d-d8d76e32602d)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(39b845ad-ccac-430e-9bae-41fdeedf2c65)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(3b4e2afe-02d8-4d8f-a27b-3ad273142592)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(4d99395c-fdea-4d9f-913c-f0664e32e652)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(563dc115-bc3e-4235-9e50-9eacf2f55639)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(6bfc4c4b-4184-4409-bb02-6de629362ba9)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(bd499306-3279-4d96-8522-ad09d90fb2cf)
Testably.Abstractions.Testing.Tests.FileSystem.FileMockTests ‑ GetUnixFileMode_SafeFileHandle_ShouldThrowPlatformNotSupportedExceptionOnWindows(c3377176-0093-4b0b-abaf-ceb8b3f4445d)
…
This pull request skips 31 tests.
Testably.Abstractions.Testing.Tests.FileSystem.DirectoryMockTests ‑ EnumerateDirectories_UnauthorizedParentAccess_ShouldThrowUnauthorizedAccessExceptionImmediately
Testably.Abstractions.Testing.Tests.FileSystem.DirectoryMockTests ‑ EnumerateFileSystemEntries_UnauthorizedParentAccess_ShouldThrowUnauthorizedAccessExceptionImmediately
Testably.Abstractions.Testing.Tests.FileSystem.DirectoryMockTests ‑ EnumerateFiles_UnauthorizedParentAccess_ShouldThrowUnauthorizedAccessExceptionImmediately
Testably.Abstractions.Testing.Tests.FileSystemInitializerExtensionsTests ‑ InitializeIn_MissingDrive_ShouldCreateDrive(my-directory)
Testably.Abstractions.Testing.Tests.MockFileSystemTests ‑ FileSystemMock_ShouldInitializeDriveFromCurrentDirectory(A:\)
Testably.Abstractions.Testing.Tests.MockFileSystemTests ‑ FileSystemMock_ShouldInitializeDriveFromCurrentDirectory(G:\)
Testably.Abstractions.Testing.Tests.MockFileSystemTests ‑ FileSystemMock_ShouldInitializeDriveFromCurrentDirectory(z:\)
Testably.Abstractions.Testing.Tests.MockFileSystemTests ‑ WithDrive_Duplicate_ShouldUpdateExistingDrive(D:\)
Testably.Abstractions.Testing.Tests.MockFileSystemTests ‑ WithDrive_NewName_ShouldCreateNewDrives(D:\)
Testably.Abstractions.Testing.Tests.MockFileSystemTests ‑ WithDrive_ShouldHavePathSeparatorSuffix(D)
…

@sonarqubecloud
Copy link
Copy Markdown

@vbreuss vbreuss merged commit 3a6ba29 into main Apr 10, 2026
13 checks passed
@vbreuss vbreuss deleted the topic/timer-changes branch April 10, 2026 04:29
@github-actions
Copy link
Copy Markdown

This is addressed in release v6.2.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working state: released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TimerMock does not wait for time to advance before invoking callback

2 participants