Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Fixes

- Update `sample_rate` of _Dynamic Sampling Context (DSC)_ when making sampling decisions ([#4374](https://github.com/getsentry/sentry-dotnet/pull/4374))
- Crontabs now support day names (MON-FRI) and allow step values and ranges to be combined ([#4407](https://github.com/getsentry/sentry-dotnet/pull/4407))

## 5.13.0

Expand Down
6 changes: 4 additions & 2 deletions src/Sentry/SentryMonitorOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,17 @@ public partial class SentryMonitorOptions : ISentryJsonSerializable
// - Allows */n for step values where n must be any positive integer (except zero)
// - Allows single values within their valid ranges
// - Allows ranges (e.g., 8-10)
// - Allows step values with ranges (e.g., 8-18/4)
// - Allows lists of values and ranges (e.g., 6,8,9 or 8-10,12-14)
// - Allows weekday names (MON, TUE, WED, THU, FRI, SAT, SUN)
//
// Valid ranges for each field:
// - Minutes: 0-59
// - Hours: 0-23
// - Days: 1-31
// - Months: 1-12
// - Weekdays: 0-7 (0 and 7 both represent Sunday)
private const string ValidCrontabPattern = @"^(\*|(\*\/([1-9][0-9]*))|([0-5]?\d)(-[0-5]?\d)?)(,([0-5]?\d)(-[0-5]?\d)?)*(\s+)(\*|(\*\/([1-9][0-9]*))|([01]?\d|2[0-3])(-([01]?\d|2[0-3]))?)((,([01]?\d|2[0-3])(-([01]?\d|2[0-3]))?)*)?(\s+)(\*|(\*\/([1-9][0-9]*))|([1-9]|[12]\d|3[01])(-([1-9]|[12]\d|3[01]))?)((,([1-9]|[12]\d|3[01])(-([1-9]|[12]\d|3[01]))?)*)?(\s+)(\*|(\*\/([1-9][0-9]*))|([1-9]|1[0-2])(-([1-9]|1[0-2]))?)((,([1-9]|1[0-2])(-([1-9]|1[0-2]))?)*)?(\s+)(\*|(\*\/([1-9][0-9]*))|[0-7](-[0-7])?)((,[0-7](-[0-7])?)*)?$";
// - Weekdays: 0-7 (0 and 7 both represent Sunday) or MON-SUN
private const string ValidCrontabPattern = @"^(\*(\/([1-9][0-9]*))?|([0-5]?\d)|([0-5]?\d)-([0-5]?\d)(\/([1-9][0-9]*))?)(,(\*(\/([1-9][0-9]*))?|([0-5]?\d)|([0-5]?\d)-([0-5]?\d)(\/([1-9][0-9]*))?))*(\s+)(\*(\/([1-9][0-9]*))?|([01]?\d|2[0-3])|([01]?\d|2[0-3])-([01]?\d|2[0-3])(\/([1-9][0-9]*))?)(,(\*(\/([1-9][0-9]*))?|([01]?\d|2[0-3])|([01]?\d|2[0-3])-([01]?\d|2[0-3])(\/([1-9][0-9]*))?))*(\s+)(\*(\/([1-9][0-9]*))?|([1-9]|[12]\d|3[01])|([1-9]|[12]\d|3[01])-([1-9]|[12]\d|3[01])(\/([1-9][0-9]*))?)(,(\*(\/([1-9][0-9]*))?|([1-9]|[12]\d|3[01])|([1-9]|[12]\d|3[01])-([1-9]|[12]\d|3[01])(\/([1-9][0-9]*))?))*(\s+)(\*(\/([1-9][0-9]*))?|([1-9]|1[0-2])|([1-9]|1[0-2])-([1-9]|1[0-2])(\/([1-9][0-9]*))?)(,(\*(\/([1-9][0-9]*))?|([1-9]|1[0-2])|([1-9]|1[0-2])-([1-9]|1[0-2])(\/([1-9][0-9]*))?))*(\s+)(\*(\/([1-9][0-9]*))?|[0-7]|(MON|TUE|WED|THU|FRI|SAT|SUN)|[0-7]-[0-7](\/([1-9][0-9]*))?|(MON|TUE|WED|THU|FRI|SAT|SUN)-(MON|TUE|WED|THU|FRI|SAT|SUN)(\/([1-9][0-9]*))?)(,(\*(\/([1-9][0-9]*))?|[0-7]|(MON|TUE|WED|THU|FRI|SAT|SUN)|[0-7]-[0-7](\/([1-9][0-9]*))?|(MON|TUE|WED|THU|FRI|SAT|SUN)-(MON|TUE|WED|THU|FRI|SAT|SUN)(\/([1-9][0-9]*))?))*$";

private SentryMonitorScheduleType _type = SentryMonitorScheduleType.None;
private string? _crontab;
Expand Down
49 changes: 49 additions & 0 deletions test/Sentry.Tests/SentryMonitorOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,33 @@ day of month 1-31
[InlineData("0 0 1 1 0")] // Minimum values
[InlineData("*/1 * * * *")] // Step of 1
[InlineData("* * 31 */2 *")] // 31st of every other month
// Weekday names
[InlineData("0 0 * * MON")]
[InlineData("0 9 * * MON-FRI")]
[InlineData("0 18 * * MON-FRI")]
[InlineData("0 0 * * MON-FRI")]
[InlineData("0 20 * * MON-FRI")]
// Step values with ranges
[InlineData("0-30/15 * * * *")] // Every 15 minutes from 0-30
[InlineData("0-59/10 * * * *")] // Every 10 minutes from 0-59
[InlineData("0-45/5 * * * *")] // Every 5 minutes from 0-45
[InlineData("* 8-18/2 * * *")] // Every 2 hours from 8-18
[InlineData("* 0-23/6 * * *")] // Every 6 hours from 0-23
[InlineData("* 9-17/1 * * *")] // Every hour from 9-17
[InlineData("* * 1-15/3 * *")] // Every 3 days from 1-15
[InlineData("* * 1-31/7 * *")] // Every 7 days from 1-31
[InlineData("* * 10-20/2 * *")] // Every 2 days from 10-20
[InlineData("* * * 1-6/2 *")] // Every 2 months from 1-6
[InlineData("* * * 1-12/3 *")] // Every 3 months from 1-12
[InlineData("* * * 3-9/1 *")] // Every month from 3-9
[InlineData("* * * * 1-5/2")] // Every 2 weekdays from 1-5 (Mon-Fri)
[InlineData("* * * * 0-6/3")] // Every 3 days of week from 0-6
[InlineData("* * * * MON-FRI/2")] // Every 2 weekdays from Mon-Fri
[InlineData("* * * * MON-SUN/3")] // Every 3 days from Mon-Sun
// Complex combinations with step values and ranges
[InlineData("0-30/15 8-18/2 * * *")] // Every 15 min from 0-30, every 2 hours from 8-18
[InlineData("0-45/5 9-17/1 1-15/3 * *")] // Complex combination
[InlineData("*/10 8-18/4 1-31/7 1-12/3 MON-FRI/2")] // All fields with step values and ranges
public void Interval_ValidCrontab_DoesNotThrow(string crontab)
{
// Arrange
Expand Down Expand Up @@ -101,6 +128,28 @@ public void Interval_SetMoreThanOnce_Throws()
[InlineData("*/* * * * *")] // Invalid step format
[InlineData(",1,2 * * * *")] // Leading comma
[InlineData("1,2, * * * *")] // Trailing comma
// Invalid step values with ranges
[InlineData("0-60/15 * * * *")] // Minute range exceeds 59
[InlineData("0-30/0 * * * *")] // Step value cannot be 0
[InlineData("0-30/-5 * * * *")] // Negative step value
[InlineData("* 8-25/2 * * *")] // Hour range exceeds 23
[InlineData("* 8-18/0 * * *")] // Step value cannot be 0
[InlineData("* * 0-31/3 * *")] // Day cannot be 0
[InlineData("* * 1-32/3 * *")] // Day range exceeds 31
[InlineData("* * * 0-12/2 *")] // Month cannot be 0
[InlineData("* * * 1-13/2 *")] // Month range exceeds 12
[InlineData("* * * * 0-8/2")] // Weekday range exceeds 7
[InlineData("* * * * MON-FRI/0")] // Step value cannot be 0
[InlineData("0-30//15 * * * *")] // Double slash
[InlineData("0-30/15/ * * * *")] // Trailing slash
[InlineData("0-30/15- * * * *")] // Incomplete range
// Invalid single value with step (should only allow step with * or ranges)
[InlineData("30/5 * * * *")] // Single minute with step
[InlineData("* 8/2 * * *")] // Single hour with step
[InlineData("* * 15/3 * *")] // Single day with step
[InlineData("* * * 6/2 *")] // Single month with step
[InlineData("* * * * 3/2")] // Single weekday with step
[InlineData("* * * * MON/2")] // Single weekday name with step
public void CaptureCheckIn_InvalidCrontabSet_Throws(string crontab)
{
// Arrange
Expand Down
Loading