Skip to content

Fix windows scheduler flaky tests#533

Merged
creativeprojects merged 4 commits intomasterfrom
fix-schtasks-flaky-tests
Mar 27, 2026
Merged

Fix windows scheduler flaky tests#533
creativeprojects merged 4 commits intomasterfrom
fix-schtasks-flaky-tests

Conversation

@creativeprojects
Copy link
Copy Markdown
Owner

No description provided.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 27, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes introduce a new mechanism for specifying a reference time ("fromNow") when creating and evaluating scheduled tasks. This affects task creation, scheduling triggers, and test logic. The trigger boundary fields are refactored to use pointers to time values instead of strings, and test suites are updated to support and normalise this new time reference for consistent results.

Changes

Cohort / File(s) Change Summary
schtasks/task.go Added fromNow field to Task, updated constructor to accept options, refactored trigger logic to use fromNow, and changed trigger boundary types to pointers to time.Time.
schtasks/task_options.go Introduced new file defining TaskOption interface, WithFromNowOption struct, and related constructor and method for setting fromNow.
schtasks/taskscheduler.go Updated createTaskDefinition to accept a from parameter and pass it as a task option; updated related function calls.
schtasks/taskscheduler_test.go Enhanced integration test to use a configurable fromNow reference, added time zone normalisation for task boundaries, and improved logging.
schtasks/trigger.go Changed StartBoundary and EndBoundary fields in trigger structs from string to *time.Time.
schtasks/trigger_test.go Updated test fixtures and calls to support new from parameter in task definition creation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15–20 minutes

Suggested labels

enhancement

✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-schtasks-flaky-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@creativeprojects creativeprojects marked this pull request as draft July 27, 2025 17:35
@creativeprojects creativeprojects changed the title Draft: enhance task scheduling with flexible time options Fix windows scheduler flaky tests Jul 27, 2025
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 63dee21 and cf8ef15.

📒 Files selected for processing (6)
  • schtasks/task.go (14 hunks)
  • schtasks/task_options.go (1 hunks)
  • schtasks/taskscheduler.go (3 hunks)
  • schtasks/taskscheduler_test.go (4 hunks)
  • schtasks/trigger.go (2 hunks)
  • schtasks/trigger_test.go (2 hunks)
🧰 Additional context used
🧠 Learnings (6)
schtasks/taskscheduler.go (2)

Learnt from: creativeprojects
PR: #425
File: schedule/handler_windows.go:97-118
Timestamp: 2025-02-04T14:38:07.701Z
Learning: The shell.SplitArguments function in the resticprofile project returns only []string and does not return any error.

Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks package, tasksPath is defined as a constant with value \resticprofile backup\ in taskscheduler.go. It's used as a prefix for managing task paths in the Windows Task Scheduler.

schtasks/trigger.go (1)

Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks package, tasksPath is defined as a constant with value \resticprofile backup\ in taskscheduler.go. It's used as a prefix for managing task paths in the Windows Task Scheduler.

schtasks/taskscheduler_test.go (1)

Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks package, tasksPath is defined as a constant with value \resticprofile backup\ in taskscheduler.go. It's used as a prefix for managing task paths in the Windows Task Scheduler.

schtasks/trigger_test.go (1)

Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks package, tasksPath is defined as a constant with value \resticprofile backup\ in taskscheduler.go. It's used as a prefix for managing task paths in the Windows Task Scheduler.

schtasks/task.go (1)

Learnt from: creativeprojects
PR: #425
File: schedule/calendar_interval.go:98-114
Timestamp: 2025-02-04T14:10:09.439Z
Learning: In schedule/calendar_interval.go, the map inside CalendarInterval is always initialized through newCalendarInterval() or clone(), so additional nil checks on the map are not needed in setCalendarIntervalValueFromType().

schtasks/task_options.go (1)

Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks package, tasksPath is defined as a constant with value \resticprofile backup\ in taskscheduler.go. It's used as a prefix for managing task paths in the Windows Task Scheduler.

🔇 Additional comments (18)
schtasks/trigger.go (1)

6-6: Type safety improvement with time package import.

Good addition to support the typed time boundaries instead of string representations.

schtasks/trigger_test.go (2)

40-40: Consistent integration with new reference time parameter.

All test fixtures properly initialise the new from field to time.Time{}, which maintains existing test behaviour whilst supporting the new reference time functionality.

Also applies to: 47-47, 55-55, 62-62, 69-69, 76-76, 84-84, 91-91, 99-99, 106-106, 113-113, 120-120, 128-128, 135-135, 142-142, 150-150, 157-157, 165-165, 172-172, 180-180, 187-187, 195-195


221-221: Function call updated to match new signature.

The call to createTaskDefinition correctly passes the new from parameter, maintaining consistency with the updated function signature.

schtasks/taskscheduler.go (3)

29-29: Required import for new time-based functionality.

Addition of the time package import supports the new reference time parameter.


170-175: Well-designed options pattern implementation.

The conditional creation of TaskOption slice and use of WithFromNow option when from is non-zero is elegant. This approach:

  • Avoids unnecessary allocations when no options are needed
  • Provides extensibility for future options
  • Maintains clean separation of concerns

55-55: Maintains backwards compatibility.

Passing time.Time{} to createTaskDefinition ensures existing behaviour is preserved whilst supporting the new reference time functionality.

schtasks/task_options.go (1)

1-22: Clean implementation of the options pattern.

This implementation follows Go idioms excellently:

  • Minimal, focused interface with single responsibility
  • Constructor function WithFromNow follows Go naming conventions
  • Options pattern provides extensibility for future task configuration
  • Clean integration with the Task.setFromNow method

The pattern allows for future expansion whilst maintaining a clean API.

schtasks/task.go (5)

33-33: Proper field design for reference time.

The fromNow field is correctly:

  • Unexported to maintain encapsulation
  • Excluded from XML serialisation with xml:"-"
  • Used as a reference time for scheduling calculations

36-80: Well-structured constructor with options pattern.

The NewTask constructor implementation is excellent:

  • Maintains backwards compatibility by initialising fromNow to current time
  • Properly applies options after base initialization
  • Follows the established options pattern consistently

The integration of the options pattern is clean and extensible.


114-117: Consistent state management in setFromNow.

The setFromNow method properly maintains consistency by updating both the fromNow field and the RegistrationInfo.Date, ensuring the task's metadata remains synchronised with its reference time.


121-121: Consistent use of reference time across all trigger methods.

All trigger creation methods (addTimeTrigger, addDailyTrigger, addWeeklyTrigger, addMonthlyTrigger) consistently use t.fromNow instead of time.Now(). This ensures:

  • Predictable scheduling behaviour
  • Better testability with controlled reference times
  • Consistent trigger calculations across the system

Also applies to: 139-139, 149-149, 163-163, 182-182, 191-191, 201-201, 216-216, 236-236, 246-246, 266-266, 276-276


121-121: Proper type alignment with trigger structure changes.

The StartBoundary assignments now use *time.Time pointers, correctly aligning with the type changes in trigger.go. This maintains type consistency across the scheduling system.

Also applies to: 149-149, 163-163, 182-182, 201-201, 216-216, 236-236, 266-266, 276-276

schtasks/taskscheduler_test.go (6)

128-166: Well-designed test fixture enhancements for time-based scheduling.

The addition of the fromNow field provides excellent test coverage for schedule evaluation from different reference points. The specific test cases for "every minute at 12" with reference times before (11:20) and after (13:20) noon effectively test boundary conditions. The commented-out test case is appropriately excluded as generating 60 triggers would be excessive for testing purposes.


171-252: Appropriate use of zero time values for backward compatibility.

Using time.Time{} for the majority of fixtures maintains existing test behaviour whilst enabling the new time reference functionality where specifically needed.


283-283: Correct parameter addition to support time reference functionality.

The updated function call properly passes the fromNow value from the test fixture to createTaskDefinition.


290-290: Useful diagnostic logging for trigger counts.

The logging statement provides valuable insight into the number of triggers generated, which is particularly helpful for debugging complex scheduling patterns.


309-311: Proper task normalisation for consistent comparison.

The approach of zeroing the fromNow field and converting trigger boundaries to UTC ensures reliable task comparison regardless of timezone differences. This addresses the Windows Task Scheduler's use of local time in XML definitions.


321-337: Well-implemented UTC conversion function with proper safety checks.

The taskInUTC function correctly handles timezone normalisation with appropriate nil pointer checks and clear documentation. The implementation properly addresses both TimeTrigger and CalendarTrigger types, ensuring consistent test results across different system timezones.

Comment thread schtasks/trigger.go
@codecov
Copy link
Copy Markdown

codecov Bot commented Jul 27, 2025

Codecov Report

❌ Patch coverage is 95.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.12%. Comparing base (cc4cec9) to head (ce789aa).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
schtasks/schtasks.go 60.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #533      +/-   ##
==========================================
+ Coverage   81.09%   81.12%   +0.02%     
==========================================
  Files         137      138       +1     
  Lines       11071    11083      +12     
==========================================
+ Hits         8978     8990      +12     
  Misses       1668     1668              
  Partials      425      425              
Flag Coverage Δ
unittests 81.12% <95.00%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@sonarqubecloud
Copy link
Copy Markdown

@sonarqubecloud
Copy link
Copy Markdown

@creativeprojects creativeprojects force-pushed the fix-schtasks-flaky-tests branch from 16944f3 to 729153b Compare March 27, 2026 22:24
@creativeprojects creativeprojects marked this pull request as ready for review March 27, 2026 22:28
Copilot AI review requested due to automatic review settings March 27, 2026 22:28
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

Adjusts Windows Task Scheduler task/trigger generation and related tests to reduce time-dependent and timezone-related flakiness when producing and round-tripping task XML.

Changes:

  • Switched trigger boundary fields from formatted strings to *time.Time for XML marshalling/unmarshalling.
  • Added an internal fromNow/WithFromNow option so tests can deterministically compute “next occurrence” times.
  • Updated unit/integration tests to tolerate timezone differences and normalize times when comparing exported/imported tasks.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
schtasks/trigger.go Change trigger boundary fields to *time.Time to improve timezone handling in XML.
schtasks/task.go Add fromNow support and update trigger creation to store boundaries as *time.Time.
schtasks/task_options.go Introduce Windows-only TaskOption + WithFromNow to set deterministic “now”.
schtasks/taskscheduler.go Thread fromNow into task creation (defaulting to current behavior when zero).
schtasks/trigger_test.go Update regex expectations for timezone, add deterministic “from” control.
schtasks/taskscheduler_test.go Add deterministic “fromNow” fixtures and normalize times to UTC before equality checks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread schtasks/task.go
Comment thread schtasks/task.go
Comment thread schtasks/task.go Outdated
Comment thread schtasks/trigger_test.go
@creativeprojects creativeprojects merged commit e2ffdfb into master Mar 27, 2026
7 checks passed
@creativeprojects creativeprojects deleted the fix-schtasks-flaky-tests branch March 27, 2026 23:16
@creativeprojects creativeprojects added this to the v0.33.0 milestone Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants