Skip to content

Commit

Permalink
Add advanced scheduling option to the test configuration (#101)
Browse files Browse the repository at this point in the history
Problem: Advanced scheduling option added to the Datadog UI was missing in the library.
Solution: Add advanced scheduling option to the test configuration in the library
  • Loading branch information
azzmiks committed Jun 20, 2023
1 parent e5860d7 commit 14a5f72
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Breaking changes

### New features & improvements
- Add advanced scheduling option to the test configuration

### Bug fixes

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package com.personio.synthetics.config

import com.datadog.api.client.v1.model.SyntheticsDeviceID
import com.datadog.api.client.v1.model.SyntheticsTestOptionsScheduling
import com.datadog.api.client.v1.model.SyntheticsTestOptionsSchedulingTimeframe
import com.datadog.api.client.v1.model.SyntheticsTestRequest
import com.personio.synthetics.client.BrowserTest
import com.personio.synthetics.model.config.Location
import com.personio.synthetics.model.config.MonitorPriority
import com.personio.synthetics.model.config.RenotifyInterval
import com.personio.synthetics.model.config.Timeframe
import java.net.URL
import java.time.ZoneId
import java.time.temporal.ChronoUnit
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.milliseconds
Expand Down Expand Up @@ -39,6 +44,31 @@ fun BrowserTest.testFrequency(frequency: Duration) = apply {
options.tickEvery = frequency.inWholeSeconds
}

/**
* Sets the advanced scheduling configuration for the synthetic browser test
* @param timeframes Time range and days when the test should be scheduled to run
* - from/to time -> pass LocalTime data type values where From value is earlier than To value
* - days -> pass comma separated DayOfWeek data type values
* @param timezone Timezone where the tests should be scheduled to run
* Pass ZoneId data type value, e.g. 'ZoneId.of("Europe/Berlin")'
* Offset value is set as the local timezone of the machine where the test creation runs, if the value is not explicitly set
* @return BrowserTest object with advanced scheduling configured
*/
fun BrowserTest.advancedScheduling(timeframes: Timeframe, timezone: ZoneId = ZoneId.systemDefault()) = apply {
require(timeframes.from < timeframes.to) {
"From time must be earlier than To time."
}
options.scheduling = SyntheticsTestOptionsScheduling()
options.scheduling.timeframes = timeframes.days.map {
SyntheticsTestOptionsSchedulingTimeframe().apply {
from = timeframes.from.truncatedTo(ChronoUnit.MINUTES).toString()
to = timeframes.to.truncatedTo(ChronoUnit.MINUTES).toString()
day = it.value
}
}
options.scheduling.timezone = timezone.toString()
}

/**
* Sets the retry count and interval for the synthetic browser test
* @param retryCount The retry count for the test
Expand Down
19 changes: 19 additions & 0 deletions src/main/kotlin/com/personio/synthetics/model/config/Timeframe.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.personio.synthetics.model.config

import java.time.DayOfWeek
import java.time.LocalTime

class Timeframe private constructor(
val from: LocalTime,
val to: LocalTime,
val days: Set<DayOfWeek>
) {
companion object {
operator fun invoke(
from: LocalTime,
to: LocalTime,
day: DayOfWeek,
vararg moreDays: DayOfWeek
) = Timeframe(from, to, setOf(day) + moreDays.toSet())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import com.personio.synthetics.client.BrowserTest
import com.personio.synthetics.model.config.Location
import com.personio.synthetics.model.config.MonitorPriority
import com.personio.synthetics.model.config.RenotifyInterval
import com.personio.synthetics.model.config.Timeframe
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import org.mockito.kotlin.mock
import java.net.URL
import java.time.DayOfWeek
import java.time.LocalTime
import java.time.ZoneId
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds

Expand Down Expand Up @@ -45,6 +51,54 @@ internal class BrowserTestConfigTest {
}
}

@Test
fun `advancedScheduling function sets the advanced scheduling in the test config`() {
browserTest.advancedScheduling(
Timeframe(
from = LocalTime.of(0, 1),
to = LocalTime.of(23, 59),
DayOfWeek.MONDAY,
DayOfWeek.SUNDAY
),
timezone = ZoneId.of("Europe/Dublin")
)

assertEquals(1, browserTest.options.scheduling.timeframes[0].day)
assertEquals("00:01", browserTest.options.scheduling.timeframes[0].from)
assertEquals("23:59", browserTest.options.scheduling.timeframes[0].to)
assertEquals(7, browserTest.options.scheduling.timeframes[1].day)
assertEquals("00:01", browserTest.options.scheduling.timeframes[1].from)
assertEquals("23:59", browserTest.options.scheduling.timeframes[1].to)
assertEquals("Europe/Dublin", browserTest.options.scheduling.timezone)
}

@Test
fun `advancedScheduling function sets the advanced scheduling with default timezone in the test config`() {
browserTest.advancedScheduling(
Timeframe(
from = LocalTime.of(0, 1),
to = LocalTime.of(23, 59),
DayOfWeek.MONDAY
)
)

assertNotNull(browserTest.options.scheduling.timezone)
assertTrue(browserTest.options.scheduling.timezone.isNotEmpty())
}

@Test
fun `advancedScheduling function throws exception when from time is later than to time`() {
assertThrows(IllegalArgumentException::class.java) {
browserTest.advancedScheduling(
Timeframe(
from = LocalTime.of(20, 0),
to = LocalTime.of(9, 0),
DayOfWeek.MONDAY
)
)
}
}

@Test
fun `retry function sets the retry count and interval in the test config`() {
browserTest.retry(1, 60.milliseconds)
Expand Down
15 changes: 15 additions & 0 deletions src/test/kotlin/com/personio/synthetics/e2e/E2ETest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.datadog.api.client.v1.model.SyntheticsCheckType
import com.datadog.api.client.v1.model.SyntheticsDeviceID
import com.datadog.api.client.v1.model.SyntheticsTestPauseStatus
import com.personio.synthetics.client.syntheticBrowserTest
import com.personio.synthetics.config.advancedScheduling
import com.personio.synthetics.config.alertMessage
import com.personio.synthetics.config.alphabeticPatternVariable
import com.personio.synthetics.config.alphanumericPatternVariable
Expand All @@ -32,6 +33,7 @@ import com.personio.synthetics.model.assertion.FileSizeCheckType
import com.personio.synthetics.model.config.Location
import com.personio.synthetics.model.config.MonitorPriority
import com.personio.synthetics.model.config.RenotifyInterval
import com.personio.synthetics.model.config.Timeframe
import com.personio.synthetics.step.api.apiStep
import com.personio.synthetics.step.assertion.currentUrlAssertion
import com.personio.synthetics.step.assertion.customJavascriptAssertion
Expand All @@ -58,6 +60,9 @@ import com.personio.synthetics.step.waitBeforeDeclaringStepAsFailed
import org.junit.jupiter.api.Test
import java.io.File
import java.net.URL
import java.time.DayOfWeek
import java.time.LocalTime
import java.time.ZoneId
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.minutes
Expand All @@ -75,6 +80,16 @@ class E2ETest {
browserAndDevice(SyntheticsDeviceID.CHROME_MOBILE_SMALL, SyntheticsDeviceID.FIREFOX_LAPTOP_LARGE)
publicLocation(Location.IRELAND_AWS, Location.N_CALIFORNIA_AWS, Location.MUMBAI_AWS)
testFrequency(6.minutes)
advancedScheduling(
Timeframe(
from = LocalTime.of(0, 1),
to = LocalTime.of(23, 59),
DayOfWeek.MONDAY,
DayOfWeek.TUESDAY,
DayOfWeek.FRIDAY
),
timezone = ZoneId.of("Europe/Dublin")
)
retry(2, 600.milliseconds)
minFailureDuration(120.minutes)
minLocationFailed(2)
Expand Down

0 comments on commit 14a5f72

Please sign in to comment.