2019-09-06 06:02:00 +02:00
package config
2019-09-09 03:07:08 +02:00
import (
2020-10-15 01:22:58 +02:00
"fmt"
2020-08-22 20:15:21 +02:00
"github.com/TwinProduction/gatus/core"
2019-09-09 03:07:08 +02:00
"testing"
"time"
)
2019-09-06 06:02:00 +02:00
2020-10-22 04:56:35 +02:00
func TestGetBeforeConfigIsLoaded ( t * testing . T ) {
defer func ( ) { recover ( ) } ( )
Get ( )
t . Fatal ( "Should've panicked because the configuration hasn't been loaded yet" )
}
func TestLoadFileThatDoesNotExist ( t * testing . T ) {
err := Load ( "file-that-does-not-exist.yaml" )
if err == nil {
t . Error ( "Should've returned an error, because the file specified doesn't exist" )
}
}
func TestLoadDefaultConfigurationFile ( t * testing . T ) {
err := LoadDefaultConfiguration ( )
if err == nil {
t . Error ( "Should've returned an error, because there's no configuration files at the default path nor the default fallback path" )
}
}
2019-10-20 04:03:55 +02:00
func TestParseAndValidateConfigBytes ( t * testing . T ) {
config , err := parseAndValidateConfigBytes ( [ ] byte ( `
2019-09-06 06:02:00 +02:00
services :
- name : twinnation
url : https : //twinnation.org/actuator/health
2019-09-09 03:07:08 +02:00
interval : 15 s
2019-09-06 06:02:00 +02:00
conditions :
2019-12-04 23:27:27 +01:00
- "[STATUS] == 200"
2019-09-06 06:02:00 +02:00
- name : github
2019-09-09 03:07:08 +02:00
url : https : //api.github.com/healthz
2019-09-06 06:02:00 +02:00
conditions :
2019-12-04 23:27:27 +01:00
- "[STATUS] != 400"
- "[STATUS] != 500"
2019-09-06 06:02:00 +02:00
` ) )
2019-10-20 04:03:55 +02:00
if err != nil {
t . Error ( "No error should've been returned" )
}
2020-08-22 20:15:21 +02:00
if config == nil {
t . Fatal ( "Config shouldn't have been nil" )
}
2019-09-06 06:02:00 +02:00
if len ( config . Services ) != 2 {
t . Error ( "Should have returned two services" )
}
2020-10-23 22:29:20 +02:00
if config . Services [ 0 ] . URL != "https://twinnation.org/actuator/health" {
2019-09-06 06:02:00 +02:00
t . Errorf ( "URL should have been %s" , "https://twinnation.org/actuator/health" )
}
2020-10-23 22:29:20 +02:00
if config . Services [ 1 ] . URL != "https://api.github.com/healthz" {
2019-09-09 03:07:08 +02:00
t . Errorf ( "URL should have been %s" , "https://api.github.com/healthz" )
2019-09-06 06:02:00 +02:00
}
2020-10-22 03:56:07 +02:00
if config . Services [ 0 ] . Method != "GET" {
t . Errorf ( "Method should have been %s (default)" , "GET" )
}
if config . Services [ 1 ] . Method != "GET" {
t . Errorf ( "Method should have been %s (default)" , "GET" )
}
2019-09-09 03:07:08 +02:00
if config . Services [ 0 ] . Interval != 15 * time . Second {
t . Errorf ( "Interval should have been %s" , 15 * time . Second )
2019-09-06 06:02:00 +02:00
}
2020-09-01 18:46:23 +02:00
if config . Services [ 1 ] . Interval != 60 * time . Second {
t . Errorf ( "Interval should have been %s, because it is the default value" , 60 * time . Second )
2019-09-06 06:02:00 +02:00
}
if len ( config . Services [ 0 ] . Conditions ) != 1 {
t . Errorf ( "There should have been %d conditions" , 1 )
}
if len ( config . Services [ 1 ] . Conditions ) != 2 {
t . Errorf ( "There should have been %d conditions" , 2 )
}
}
2019-09-10 04:21:18 +02:00
2019-10-20 04:03:55 +02:00
func TestParseAndValidateConfigBytesDefault ( t * testing . T ) {
config , err := parseAndValidateConfigBytes ( [ ] byte ( `
2019-09-10 04:21:18 +02:00
services :
- name : twinnation
url : https : //twinnation.org/actuator/health
conditions :
2019-12-04 23:27:27 +01:00
- "[STATUS] == 200"
2019-09-10 04:21:18 +02:00
` ) )
2019-10-20 04:03:55 +02:00
if err != nil {
t . Error ( "No error should've been returned" )
}
2020-08-22 20:15:21 +02:00
if config == nil {
t . Fatal ( "Config shouldn't have been nil" )
}
2019-11-16 21:47:56 +01:00
if config . Metrics {
t . Error ( "Metrics should've been false by default" )
}
2020-10-23 22:29:20 +02:00
if config . Services [ 0 ] . URL != "https://twinnation.org/actuator/health" {
2019-11-16 21:47:56 +01:00
t . Errorf ( "URL should have been %s" , "https://twinnation.org/actuator/health" )
}
2020-09-01 18:46:23 +02:00
if config . Services [ 0 ] . Interval != 60 * time . Second {
t . Errorf ( "Interval should have been %s, because it is the default value" , 60 * time . Second )
2019-11-16 21:47:56 +01:00
}
}
func TestParseAndValidateConfigBytesWithMetrics ( t * testing . T ) {
config , err := parseAndValidateConfigBytes ( [ ] byte ( `
metrics : true
services :
- name : twinnation
url : https : //twinnation.org/actuator/health
conditions :
2019-12-04 23:27:27 +01:00
- "[STATUS] == 200"
2019-11-16 21:47:56 +01:00
` ) )
if err != nil {
t . Error ( "No error should've been returned" )
}
2020-08-22 20:15:21 +02:00
if config == nil {
t . Fatal ( "Config shouldn't have been nil" )
}
2019-11-16 21:47:56 +01:00
if ! config . Metrics {
t . Error ( "Metrics should have been true" )
}
2020-10-23 22:29:20 +02:00
if config . Services [ 0 ] . URL != "https://twinnation.org/actuator/health" {
2019-09-10 04:21:18 +02:00
t . Errorf ( "URL should have been %s" , "https://twinnation.org/actuator/health" )
}
2020-09-01 18:46:23 +02:00
if config . Services [ 0 ] . Interval != 60 * time . Second {
t . Errorf ( "Interval should have been %s, because it is the default value" , 60 * time . Second )
2019-09-10 04:21:18 +02:00
}
}
2019-10-20 04:03:55 +02:00
func TestParseAndValidateBadConfigBytes ( t * testing . T ) {
_ , err := parseAndValidateConfigBytes ( [ ] byte ( `
badconfig :
- asdsa : w0w
usadasdrl : asdxzczxc
asdas :
- soup
` ) )
if err == nil {
t . Error ( "An error should've been returned" )
}
if err != ErrNoServiceInConfig {
t . Error ( "The error returned should have been of type ErrNoServiceInConfig" )
}
}
2020-08-22 20:15:21 +02:00
func TestParseAndValidateConfigBytesWithAlerting ( t * testing . T ) {
config , err := parseAndValidateConfigBytes ( [ ] byte ( `
alerting :
2020-09-19 22:22:12 +02:00
slack :
webhook - url : "http://example.com"
2020-09-25 01:52:59 +02:00
pagerduty :
integration - key : "00000000000000000000000000000000"
2020-08-22 20:15:21 +02:00
services :
- name : twinnation
url : https : //twinnation.org/actuator/health
alerts :
- type : slack
enabled : true
2020-10-22 03:56:07 +02:00
- type : pagerduty
enabled : true
2020-09-17 02:22:33 +02:00
failure - threshold : 7
2020-10-22 03:56:07 +02:00
success - threshold : 5
2020-08-22 20:15:21 +02:00
description : "Healthcheck failed 7 times in a row"
conditions :
- "[STATUS] == 200"
` ) )
if err != nil {
t . Error ( "No error should've been returned" )
}
if config == nil {
t . Fatal ( "Config shouldn't have been nil" )
}
if config . Metrics {
t . Error ( "Metrics should've been false by default" )
}
if config . Alerting == nil {
2020-09-25 01:52:59 +02:00
t . Fatal ( "config.Alerting shouldn't have been nil" )
}
if config . Alerting . Slack == nil || ! config . Alerting . Slack . IsValid ( ) {
t . Fatal ( "Slack alerting config should've been valid" )
2020-08-22 20:15:21 +02:00
}
2020-10-23 22:29:20 +02:00
if config . Alerting . Slack . WebhookURL != "http://example.com" {
t . Errorf ( "Slack webhook should've been %s, but was %s" , "http://example.com" , config . Alerting . Slack . WebhookURL )
2020-09-25 01:52:59 +02:00
}
if config . Alerting . PagerDuty == nil || ! config . Alerting . PagerDuty . IsValid ( ) {
t . Fatal ( "PagerDuty alerting config should've been valid" )
}
if config . Alerting . PagerDuty . IntegrationKey != "00000000000000000000000000000000" {
t . Errorf ( "PagerDuty integration key should've been %s, but was %s" , "00000000000000000000000000000000" , config . Alerting . PagerDuty . IntegrationKey )
2020-08-22 20:15:21 +02:00
}
if len ( config . Services ) != 1 {
t . Error ( "There should've been 1 service" )
}
2020-10-23 22:29:20 +02:00
if config . Services [ 0 ] . URL != "https://twinnation.org/actuator/health" {
2020-08-22 20:15:21 +02:00
t . Errorf ( "URL should have been %s" , "https://twinnation.org/actuator/health" )
}
2020-09-01 18:46:23 +02:00
if config . Services [ 0 ] . Interval != 60 * time . Second {
t . Errorf ( "Interval should have been %s, because it is the default value" , 60 * time . Second )
2020-08-22 20:15:21 +02:00
}
if config . Services [ 0 ] . Alerts == nil {
t . Fatal ( "The service alerts shouldn't have been nil" )
}
2020-10-22 03:56:07 +02:00
if len ( config . Services [ 0 ] . Alerts ) != 2 {
t . Fatal ( "There should've been 2 alert configured" )
2020-08-22 20:15:21 +02:00
}
if ! config . Services [ 0 ] . Alerts [ 0 ] . Enabled {
t . Error ( "The alert should've been enabled" )
}
2020-10-22 03:56:07 +02:00
if config . Services [ 0 ] . Alerts [ 0 ] . FailureThreshold != 3 {
t . Errorf ( "The default failure threshold of the alert should've been %d, but it was %d" , 3 , config . Services [ 0 ] . Alerts [ 0 ] . FailureThreshold )
}
if config . Services [ 0 ] . Alerts [ 0 ] . SuccessThreshold != 2 {
t . Errorf ( "The default success threshold of the alert should've been %d, but it was %d" , 2 , config . Services [ 0 ] . Alerts [ 0 ] . SuccessThreshold )
2020-09-17 02:22:33 +02:00
}
2020-10-22 03:56:07 +02:00
if config . Services [ 0 ] . Alerts [ 1 ] . FailureThreshold != 7 {
t . Errorf ( "The failure threshold of the alert should've been %d, but it was %d" , 7 , config . Services [ 0 ] . Alerts [ 1 ] . FailureThreshold )
}
if config . Services [ 0 ] . Alerts [ 1 ] . SuccessThreshold != 5 {
t . Errorf ( "The success threshold of the alert should've been %d, but it was %d" , 5 , config . Services [ 0 ] . Alerts [ 1 ] . SuccessThreshold )
2020-08-22 20:15:21 +02:00
}
if config . Services [ 0 ] . Alerts [ 0 ] . Type != core . SlackAlert {
t . Errorf ( "The type of the alert should've been %s, but it was %s" , core . SlackAlert , config . Services [ 0 ] . Alerts [ 0 ] . Type )
}
2020-10-22 03:56:07 +02:00
if config . Services [ 0 ] . Alerts [ 1 ] . Type != core . PagerDutyAlert {
t . Errorf ( "The type of the alert should've been %s, but it was %s" , core . PagerDutyAlert , config . Services [ 0 ] . Alerts [ 1 ] . Type )
}
if config . Services [ 0 ] . Alerts [ 1 ] . Description != "Healthcheck failed 7 times in a row" {
t . Errorf ( "The description of the alert should've been %s, but it was %s" , "Healthcheck failed 7 times in a row" , config . Services [ 0 ] . Alerts [ 0 ] . Description )
2020-08-22 20:15:21 +02:00
}
}
2020-09-25 01:52:59 +02:00
func TestParseAndValidateConfigBytesWithInvalidPagerDutyAlertingConfig ( t * testing . T ) {
config , err := parseAndValidateConfigBytes ( [ ] byte ( `
alerting :
pagerduty :
integration - key : "INVALID_KEY"
services :
- name : twinnation
url : https : //twinnation.org/actuator/health
2020-10-22 03:56:07 +02:00
alerts :
- type : pagerduty
2020-09-25 01:52:59 +02:00
conditions :
- "[STATUS] == 200"
` ) )
if err != nil {
t . Error ( "No error should've been returned" )
}
if config == nil {
t . Fatal ( "Config shouldn't have been nil" )
}
if config . Alerting == nil {
t . Fatal ( "config.Alerting shouldn't have been nil" )
}
if config . Alerting . PagerDuty == nil {
t . Fatal ( "PagerDuty alerting config shouldn't have been nil" )
}
if config . Alerting . PagerDuty . IsValid ( ) {
t . Fatal ( "PagerDuty alerting config should've been invalid" )
}
}
2020-10-15 01:22:58 +02:00
func TestParseAndValidateConfigBytesWithInvalidSecurityConfig ( t * testing . T ) {
defer func ( ) { recover ( ) } ( )
_ , _ = parseAndValidateConfigBytes ( [ ] byte ( `
security :
basic :
username : "admin"
password - sha512 : "invalid-sha512-hash"
services :
- name : twinnation
url : https : //twinnation.org/actuator/health
conditions :
- "[STATUS] == 200"
` ) )
t . Error ( "Function should've panicked" )
}
func TestParseAndValidateConfigBytesWithValidSecurityConfig ( t * testing . T ) {
const expectedUsername = "admin"
const expectedPasswordHash = "6b97ed68d14eb3f1aa959ce5d49c7dc612e1eb1dafd73b1e705847483fd6a6c809f2ceb4e8df6ff9984c6298ff0285cace6614bf8daa9f0070101b6c89899e22"
config , err := parseAndValidateConfigBytes ( [ ] byte ( fmt . Sprintf ( `
security :
basic :
username : "%s"
password - sha512 : "%s"
services :
- name : twinnation
url : https : //twinnation.org/actuator/health
conditions :
- "[STATUS] == 200"
` , expectedUsername , expectedPasswordHash ) ) )
if err != nil {
t . Error ( "No error should've been returned" )
}
if config == nil {
t . Fatal ( "Config shouldn't have been nil" )
}
if config . Security == nil {
t . Fatal ( "config.Security shouldn't have been nil" )
}
if ! config . Security . IsValid ( ) {
t . Error ( "Security config should've been valid" )
}
if config . Security . Basic == nil {
t . Fatal ( "config.Security.Basic shouldn't have been nil" )
}
if config . Security . Basic . Username != expectedUsername {
t . Errorf ( "config.Security.Basic.Username should've been %s, but was %s" , expectedUsername , config . Security . Basic . Username )
}
if config . Security . Basic . PasswordSha512Hash != expectedPasswordHash {
t . Errorf ( "config.Security.Basic.PasswordSha512Hash should've been %s, but was %s" , expectedPasswordHash , config . Security . Basic . PasswordSha512Hash )
}
}