2021-01-10 04:55:36 +01:00
package watchdog
import (
2021-01-10 07:22:27 +01:00
"os"
2021-01-10 04:55:36 +01:00
"testing"
2021-10-04 03:53:59 +02:00
"github.com/TwinProduction/gatus/v3/alerting"
"github.com/TwinProduction/gatus/v3/alerting/alert"
"github.com/TwinProduction/gatus/v3/alerting/provider/custom"
"github.com/TwinProduction/gatus/v3/alerting/provider/pagerduty"
"github.com/TwinProduction/gatus/v3/config"
"github.com/TwinProduction/gatus/v3/core"
2021-01-10 04:55:36 +01:00
)
func TestHandleAlerting ( t * testing . T ) {
2021-01-10 07:22:27 +01:00
_ = os . Setenv ( "MOCK_ALERT_PROVIDER" , "true" )
defer os . Clearenv ( )
2021-01-10 04:55:36 +01:00
cfg := & config . Config {
2021-01-10 05:52:11 +01:00
Debug : true ,
2021-01-10 04:55:36 +01:00
Alerting : & alerting . Config {
Custom : & custom . AlertProvider {
2021-09-18 18:42:11 +02:00
URL : "https://twin.sh/health" ,
2021-01-10 04:55:36 +01:00
Method : "GET" ,
} ,
} ,
}
2021-05-16 03:54:23 +02:00
enabled := true
2021-01-10 04:55:36 +01:00
service := & core . Service {
URL : "http://example.com" ,
2021-05-19 04:29:15 +02:00
Alerts : [ ] * alert . Alert {
2021-01-10 04:55:36 +01:00
{
2021-05-19 04:29:15 +02:00
Type : alert . TypeCustom ,
2021-05-16 03:54:23 +02:00
Enabled : & enabled ,
2021-01-10 04:55:36 +01:00
FailureThreshold : 2 ,
SuccessThreshold : 3 ,
2021-05-16 03:54:23 +02:00
SendOnResolved : & enabled ,
2021-01-10 04:55:36 +01:00
Triggered : false ,
} ,
} ,
}
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 0 , false , "The alert shouldn't start triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 1 , 0 , false , "The alert shouldn't have triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 2 , 0 , true , "The alert should've triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 3 , 0 , true , "The alert should still be triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 4 , 0 , true , "The alert should still be triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 1 , true , "The alert should still be triggered (because service.Alerts[0].SuccessThreshold is 3)" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 2 , true , "The alert should still be triggered (because service.Alerts[0].SuccessThreshold is 3)" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 3 , false , "The alert should've been resolved" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 4 , false , "The alert should no longer be triggered" )
2021-01-10 04:55:36 +01:00
}
2021-01-10 05:52:11 +01:00
func TestHandleAlertingWhenAlertingConfigIsNil ( t * testing . T ) {
2021-01-10 07:22:27 +01:00
_ = os . Setenv ( "MOCK_ALERT_PROVIDER" , "true" )
defer os . Clearenv ( )
2021-05-19 04:29:15 +02:00
HandleAlerting ( nil , nil , nil , true )
2021-01-10 05:52:11 +01:00
}
func TestHandleAlertingWithBadAlertProvider ( t * testing . T ) {
2021-01-10 07:22:27 +01:00
_ = os . Setenv ( "MOCK_ALERT_PROVIDER" , "true" )
defer os . Clearenv ( )
2021-05-16 03:54:23 +02:00
enabled := true
2021-01-10 05:52:11 +01:00
service := & core . Service {
URL : "http://example.com" ,
2021-05-19 04:29:15 +02:00
Alerts : [ ] * alert . Alert {
2021-01-10 05:52:11 +01:00
{
2021-05-19 04:29:15 +02:00
Type : alert . TypeCustom ,
2021-05-16 03:54:23 +02:00
Enabled : & enabled ,
2021-01-10 05:52:11 +01:00
FailureThreshold : 1 ,
SuccessThreshold : 1 ,
2021-05-16 03:54:23 +02:00
SendOnResolved : & enabled ,
2021-01-10 05:52:11 +01:00
Triggered : false ,
} ,
} ,
}
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 0 , false , "The alert shouldn't start triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , & alerting . Config { } , false )
2021-01-21 22:14:32 +01:00
verify ( t , service , 1 , 0 , false , "The alert shouldn't have triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , & alerting . Config { } , false )
2021-01-21 22:14:32 +01:00
verify ( t , service , 2 , 0 , false , "The alert shouldn't have triggered, because the provider wasn't configured properly" )
2021-01-10 05:52:11 +01:00
}
2021-01-10 06:24:31 +01:00
func TestHandleAlertingWhenTriggeredAlertIsAlmostResolvedButServiceStartFailingAgain ( t * testing . T ) {
2021-01-10 07:22:27 +01:00
_ = os . Setenv ( "MOCK_ALERT_PROVIDER" , "true" )
defer os . Clearenv ( )
2021-01-10 06:24:31 +01:00
cfg := & config . Config {
Debug : true ,
Alerting : & alerting . Config {
Custom : & custom . AlertProvider {
2021-09-18 18:42:11 +02:00
URL : "https://twin.sh/health" ,
2021-01-10 06:24:31 +01:00
Method : "GET" ,
} ,
} ,
}
2021-05-16 03:54:23 +02:00
enabled := true
2021-01-10 06:24:31 +01:00
service := & core . Service {
URL : "http://example.com" ,
2021-05-19 04:29:15 +02:00
Alerts : [ ] * alert . Alert {
2021-01-10 06:24:31 +01:00
{
2021-05-19 04:29:15 +02:00
Type : alert . TypeCustom ,
2021-05-16 03:54:23 +02:00
Enabled : & enabled ,
2021-01-10 06:24:31 +01:00
FailureThreshold : 2 ,
SuccessThreshold : 3 ,
2021-05-16 03:54:23 +02:00
SendOnResolved : & enabled ,
2021-01-10 06:24:31 +01:00
Triggered : true ,
} ,
} ,
NumberOfFailuresInARow : 1 ,
}
// This test simulate an alert that was already triggered
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 2 , 0 , true , "The alert was already triggered at the beginning of this test" )
2021-01-10 06:24:31 +01:00
}
2021-01-10 07:22:27 +01:00
2021-01-10 07:32:50 +01:00
func TestHandleAlertingWhenTriggeredAlertIsResolvedButSendOnResolvedIsFalse ( t * testing . T ) {
_ = os . Setenv ( "MOCK_ALERT_PROVIDER" , "true" )
defer os . Clearenv ( )
cfg := & config . Config {
Debug : true ,
Alerting : & alerting . Config {
Custom : & custom . AlertProvider {
2021-09-18 18:42:11 +02:00
URL : "https://twin.sh/health" ,
2021-01-10 07:32:50 +01:00
Method : "GET" ,
} ,
} ,
}
2021-05-16 03:54:23 +02:00
enabled := true
disabled := false
2021-01-10 07:32:50 +01:00
service := & core . Service {
URL : "http://example.com" ,
2021-05-19 04:29:15 +02:00
Alerts : [ ] * alert . Alert {
2021-01-10 07:32:50 +01:00
{
2021-05-19 04:29:15 +02:00
Type : alert . TypeCustom ,
2021-05-16 03:54:23 +02:00
Enabled : & enabled ,
2021-01-10 07:32:50 +01:00
FailureThreshold : 1 ,
SuccessThreshold : 1 ,
2021-05-16 03:54:23 +02:00
SendOnResolved : & disabled ,
2021-01-10 07:32:50 +01:00
Triggered : true ,
} ,
} ,
NumberOfFailuresInARow : 1 ,
}
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 1 , false , "The alert should've been resolved" )
2021-01-10 07:32:50 +01:00
}
2021-01-10 07:22:27 +01:00
func TestHandleAlertingWhenTriggeredAlertIsResolvedPagerDuty ( t * testing . T ) {
_ = os . Setenv ( "MOCK_ALERT_PROVIDER" , "true" )
defer os . Clearenv ( )
cfg := & config . Config {
Debug : true ,
Alerting : & alerting . Config {
PagerDuty : & pagerduty . AlertProvider {
IntegrationKey : "00000000000000000000000000000000" ,
} ,
} ,
}
2021-05-16 03:54:23 +02:00
enabled := true
2021-01-10 07:22:27 +01:00
service := & core . Service {
URL : "http://example.com" ,
2021-05-19 04:29:15 +02:00
Alerts : [ ] * alert . Alert {
2021-01-10 07:22:27 +01:00
{
2021-05-19 04:29:15 +02:00
Type : alert . TypePagerDuty ,
2021-05-16 03:54:23 +02:00
Enabled : & enabled ,
2021-01-10 07:22:27 +01:00
FailureThreshold : 1 ,
SuccessThreshold : 1 ,
2021-05-16 03:54:23 +02:00
SendOnResolved : & enabled ,
2021-01-10 07:22:27 +01:00
Triggered : false ,
} ,
} ,
NumberOfFailuresInARow : 0 ,
}
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 1 , 0 , true , "" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 1 , false , "The alert should've been resolved" )
}
func TestHandleAlertingWithProviderThatReturnsAnError ( t * testing . T ) {
_ = os . Setenv ( "MOCK_ALERT_PROVIDER" , "true" )
defer os . Clearenv ( )
cfg := & config . Config {
Debug : true ,
Alerting : & alerting . Config {
Custom : & custom . AlertProvider {
2021-09-18 18:42:11 +02:00
URL : "https://twin.sh/health" ,
2021-01-21 22:14:32 +01:00
Method : "GET" ,
} ,
} ,
2021-01-10 07:22:27 +01:00
}
2021-05-16 03:54:23 +02:00
enabled := true
2021-01-21 22:14:32 +01:00
service := & core . Service {
URL : "http://example.com" ,
2021-05-19 04:29:15 +02:00
Alerts : [ ] * alert . Alert {
2021-01-21 22:14:32 +01:00
{
2021-05-19 04:29:15 +02:00
Type : alert . TypeCustom ,
2021-05-16 03:54:23 +02:00
Enabled : & enabled ,
2021-01-21 22:14:32 +01:00
FailureThreshold : 2 ,
SuccessThreshold : 2 ,
2021-05-16 03:54:23 +02:00
SendOnResolved : & enabled ,
2021-01-21 22:14:32 +01:00
Triggered : false ,
} ,
} ,
2021-01-10 07:22:27 +01:00
}
2021-01-21 22:14:32 +01:00
_ = os . Setenv ( "MOCK_ALERT_PROVIDER_ERROR" , "true" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 1 , 0 , false , "" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 2 , 0 , false , "The alert should have failed to trigger, because the alert provider is returning an error" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 3 , 0 , false , "The alert should still not be triggered, because the alert provider is still returning an error" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 4 , 0 , false , "The alert should still not be triggered, because the alert provider is still returning an error" )
_ = os . Setenv ( "MOCK_ALERT_PROVIDER_ERROR" , "false" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 5 , 0 , true , "The alert should've been triggered because the alert provider is no longer returning an error" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 1 , true , "The alert should've still been triggered" )
_ = os . Setenv ( "MOCK_ALERT_PROVIDER_ERROR" , "true" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 2 , false , "The alert should've been resolved DESPITE THE ALERT PROVIDER RETURNING AN ERROR. See Alert.Triggered for further explanation." )
_ = os . Setenv ( "MOCK_ALERT_PROVIDER_ERROR" , "false" )
// Make sure that everything's working as expected after a rough patch
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 1 , 0 , false , "" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 2 , 0 , true , "The alert should have triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 1 , true , "The alert should still be triggered" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 2 , false , "The alert should have been resolved" )
}
func TestHandleAlertingWithProviderThatOnlyReturnsErrorOnResolve ( t * testing . T ) {
_ = os . Setenv ( "MOCK_ALERT_PROVIDER" , "true" )
defer os . Clearenv ( )
cfg := & config . Config {
Debug : true ,
Alerting : & alerting . Config {
Custom : & custom . AlertProvider {
2021-09-18 18:42:11 +02:00
URL : "https://twin.sh/health" ,
2021-01-21 22:14:32 +01:00
Method : "GET" ,
} ,
} ,
2021-01-10 07:22:27 +01:00
}
2021-05-16 03:54:23 +02:00
enabled := true
2021-01-21 22:14:32 +01:00
service := & core . Service {
URL : "http://example.com" ,
2021-05-19 04:29:15 +02:00
Alerts : [ ] * alert . Alert {
2021-01-21 22:14:32 +01:00
{
2021-05-19 04:29:15 +02:00
Type : alert . TypeCustom ,
2021-05-16 03:54:23 +02:00
Enabled : & enabled ,
2021-01-21 22:14:32 +01:00
FailureThreshold : 1 ,
SuccessThreshold : 1 ,
2021-05-16 03:54:23 +02:00
SendOnResolved : & enabled ,
2021-01-21 22:14:32 +01:00
Triggered : false ,
} ,
} ,
2021-01-10 07:22:27 +01:00
}
2021-01-21 22:14:32 +01:00
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 1 , 0 , true , "" )
_ = os . Setenv ( "MOCK_ALERT_PROVIDER_ERROR" , "true" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 0 , 1 , false , "" )
_ = os . Setenv ( "MOCK_ALERT_PROVIDER_ERROR" , "false" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:14:32 +01:00
verify ( t , service , 1 , 0 , true , "" )
_ = os . Setenv ( "MOCK_ALERT_PROVIDER_ERROR" , "true" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:34:40 +01:00
verify ( t , service , 0 , 1 , false , "" )
2021-01-21 22:14:32 +01:00
_ = os . Setenv ( "MOCK_ALERT_PROVIDER_ERROR" , "false" )
// Make sure that everything's working as expected after a rough patch
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:34:40 +01:00
verify ( t , service , 1 , 0 , true , "" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : false } , cfg . Alerting , cfg . Debug )
2021-01-21 22:34:40 +01:00
verify ( t , service , 2 , 0 , true , "" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:34:40 +01:00
verify ( t , service , 0 , 1 , false , "" )
2021-05-19 04:29:15 +02:00
HandleAlerting ( service , & core . Result { Success : true } , cfg . Alerting , cfg . Debug )
2021-01-21 22:34:40 +01:00
verify ( t , service , 0 , 2 , false , "" )
2021-01-21 22:14:32 +01:00
}
func verify ( t * testing . T , service * core . Service , expectedNumberOfFailuresInARow , expectedNumberOfSuccessInARow int , expectedTriggered bool , expectedTriggeredReason string ) {
if service . NumberOfFailuresInARow != expectedNumberOfFailuresInARow {
t . Fatalf ( "service.NumberOfFailuresInARow should've been %d, got %d" , expectedNumberOfFailuresInARow , service . NumberOfFailuresInARow )
}
if service . NumberOfSuccessesInARow != expectedNumberOfSuccessInARow {
t . Fatalf ( "service.NumberOfSuccessesInARow should've been %d, got %d" , expectedNumberOfSuccessInARow , service . NumberOfSuccessesInARow )
}
if service . Alerts [ 0 ] . Triggered != expectedTriggered {
if len ( expectedTriggeredReason ) != 0 {
t . Fatal ( expectedTriggeredReason )
} else {
if expectedTriggered {
t . Fatal ( "The alert should've been triggered" )
} else {
t . Fatal ( "The alert shouldn't have been triggered" )
}
}
2021-01-10 07:22:27 +01:00
}
}