2020-12-30 11:57:17 +01:00
package storage
import (
"fmt"
"testing"
"time"
"github.com/TwinProduction/gatus/core"
)
var testService = core . Service {
Name : "Name" ,
Group : "Group" ,
URL : "URL" ,
DNS : & core . DNS { QueryType : "QueryType" , QueryName : "QueryName" } ,
Method : "Method" ,
Body : "Body" ,
GraphQL : false ,
Headers : nil ,
Interval : time . Second * 2 ,
Conditions : nil ,
Alerts : nil ,
Insecure : false ,
NumberOfFailuresInARow : 0 ,
NumberOfSuccessesInARow : 0 ,
}
var memoryStore = NewInMemoryStore ( )
func TestStorage_GetAllFromEmptyMemoryStoreReturnsNothing ( t * testing . T ) {
memoryStore . Clear ( )
results := memoryStore . GetAll ( )
if len ( results ) != 0 {
t . Errorf ( "MemoryStore should've returned 0 results, but actually returned %d" , len ( results ) )
}
}
func TestStorage_InsertIntoEmptyMemoryStoreThenGetAllReturnsOneResult ( t * testing . T ) {
memoryStore . Clear ( )
result := core . Result {
HTTPStatus : 200 ,
DNSRCode : "DNSRCode" ,
Body : nil ,
Hostname : "Hostname" ,
IP : "IP" ,
Connected : false ,
Duration : time . Second * 2 ,
Errors : nil ,
ConditionResults : nil ,
Success : false ,
Timestamp : time . Now ( ) ,
CertificateExpiration : time . Second * 2 ,
}
memoryStore . Insert ( & testService , & result )
results := memoryStore . GetAll ( )
if len ( results ) != 1 {
t . Errorf ( "MemoryStore should've returned 0 results, but actually returned %d" , len ( results ) )
}
key := fmt . Sprintf ( "%s_%s" , testService . Group , testService . Name )
storedResult , exists := results [ key ]
if ! exists {
t . Fatalf ( "In Memory Store should've contained key '%s', but didn't" , key )
}
if storedResult . Name != testService . Name {
t . Errorf ( "Stored Results Name should've been %s, but was %s" , testService . Name , storedResult . Name )
}
if storedResult . Group != testService . Group {
t . Errorf ( "Stored Results Group should've been %s, but was %s" , testService . Group , storedResult . Group )
}
if len ( storedResult . Results ) != 1 {
t . Errorf ( "Stored Results for service %s should've had 1 result, but actually had %d" , storedResult . Name , len ( storedResult . Results ) )
}
if storedResult . Results [ 0 ] == & result {
t . Errorf ( "Returned result is the same reference as result passed to insert. Returned result should be copies only" )
}
}
func TestStorage_InsertTwoResultsForSingleServiceIntoEmptyMemoryStore_ThenGetAllReturnsTwoResults ( t * testing . T ) {
memoryStore . Clear ( )
result1 := core . Result {
HTTPStatus : 404 ,
DNSRCode : "DNSRCode" ,
Body : nil ,
Hostname : "Hostname" ,
IP : "IP" ,
Connected : false ,
Duration : time . Second * 2 ,
Errors : nil ,
ConditionResults : nil ,
Success : false ,
Timestamp : time . Now ( ) ,
CertificateExpiration : time . Second * 2 ,
}
result2 := core . Result {
HTTPStatus : 200 ,
DNSRCode : "DNSRCode" ,
Body : nil ,
Hostname : "Hostname" ,
IP : "IP" ,
Connected : true ,
Duration : time . Second * 2 ,
Errors : nil ,
ConditionResults : nil ,
2021-01-08 23:43:45 +01:00
Success : false ,
2020-12-30 11:57:17 +01:00
Timestamp : time . Now ( ) ,
CertificateExpiration : time . Second * 2 ,
}
resultsToInsert := [ ] core . Result { result1 , result2 }
memoryStore . Insert ( & testService , & result1 )
memoryStore . Insert ( & testService , & result2 )
results := memoryStore . GetAll ( )
if len ( results ) != 1 {
t . Fatalf ( "MemoryStore should've returned 1 results, but actually returned %d" , len ( results ) )
}
key := fmt . Sprintf ( "%s_%s" , testService . Group , testService . Name )
serviceResults , exists := results [ key ]
if ! exists {
t . Fatalf ( "In Memory Store should've contained key '%s', but didn't" , key )
}
if len ( serviceResults . Results ) != 2 {
t . Fatalf ( "Service '%s' should've had 2 results, but actually returned %d" , serviceResults . Name , len ( serviceResults . Results ) )
}
for i , r := range serviceResults . Results {
expectedResult := resultsToInsert [ i ]
if r . HTTPStatus != expectedResult . HTTPStatus {
t . Errorf ( "Result at index %d should've had a HTTPStatus of %d, but was actually %d" , i , expectedResult . HTTPStatus , r . HTTPStatus )
}
if r . DNSRCode != expectedResult . DNSRCode {
t . Errorf ( "Result at index %d should've had a DNSRCode of %s, but was actually %s" , i , expectedResult . DNSRCode , r . DNSRCode )
}
if len ( r . Body ) != len ( expectedResult . Body ) {
t . Errorf ( "Result at index %d should've had a body of length %d, but was actually %d" , i , len ( expectedResult . Body ) , len ( r . Body ) )
}
if r . Hostname != expectedResult . Hostname {
t . Errorf ( "Result at index %d should've had a Hostname of %s, but was actually %s" , i , expectedResult . Hostname , r . Hostname )
}
if r . IP != expectedResult . IP {
t . Errorf ( "Result at index %d should've had a IP of %s, but was actually %s" , i , expectedResult . IP , r . IP )
}
if r . Connected != expectedResult . Connected {
t . Errorf ( "Result at index %d should've had a Connected value of %t, but was actually %t" , i , expectedResult . Connected , r . Connected )
}
if r . Duration != expectedResult . Duration {
t . Errorf ( "Result at index %d should've had a Duration of %s, but was actually %s" , i , expectedResult . Duration . String ( ) , r . Duration . String ( ) )
}
if len ( r . Errors ) != len ( expectedResult . Errors ) {
t . Errorf ( "Result at index %d should've had %d errors, but actually had %d errors" , i , len ( expectedResult . Errors ) , len ( r . Errors ) )
}
if len ( r . ConditionResults ) != len ( expectedResult . ConditionResults ) {
t . Errorf ( "Result at index %d should've had %d ConditionResults, but actually had %d ConditionResults" , i , len ( expectedResult . ConditionResults ) , len ( r . ConditionResults ) )
}
if r . Success != expectedResult . Success {
t . Errorf ( "Result at index %d should've had a Success of %t, but was actually %t" , i , expectedResult . Success , r . Success )
}
if r . Timestamp != expectedResult . Timestamp {
t . Errorf ( "Result at index %d should've had a Timestamp of %s, but was actually %s" , i , expectedResult . Timestamp . String ( ) , r . Timestamp . String ( ) )
}
if r . CertificateExpiration != expectedResult . CertificateExpiration {
t . Errorf ( "Result at index %d should've had a CertificateExpiration of %s, but was actually %s" , i , expectedResult . CertificateExpiration . String ( ) , r . CertificateExpiration . String ( ) )
}
}
}
func TestStorage_InsertTwoResultsTwoServicesIntoEmptyMemoryStore_ThenGetAllReturnsTwoServicesWithOneResultEach ( t * testing . T ) {
memoryStore . Clear ( )
result1 := core . Result {
HTTPStatus : 404 ,
DNSRCode : "DNSRCode" ,
Body : nil ,
Hostname : "Hostname" ,
IP : "IP" ,
Connected : false ,
Duration : time . Second * 2 ,
Errors : nil ,
ConditionResults : nil ,
Success : false ,
Timestamp : time . Now ( ) ,
CertificateExpiration : time . Second * 2 ,
}
result2 := core . Result {
HTTPStatus : 200 ,
DNSRCode : "DNSRCode" ,
Body : nil ,
Hostname : "Hostname" ,
IP : "IP" ,
Connected : true ,
Duration : time . Second * 2 ,
Errors : nil ,
ConditionResults : nil ,
Success : true ,
Timestamp : time . Now ( ) ,
CertificateExpiration : time . Second * 2 ,
}
testService2 := core . Service {
Name : "Name2" ,
Group : "Group" ,
URL : "URL" ,
DNS : & core . DNS { QueryType : "QueryType" , QueryName : "QueryName" } ,
Method : "Method" ,
Body : "Body" ,
GraphQL : false ,
Headers : nil ,
Interval : time . Second * 2 ,
Conditions : nil ,
Alerts : nil ,
Insecure : false ,
NumberOfFailuresInARow : 0 ,
NumberOfSuccessesInARow : 0 ,
}
memoryStore . Insert ( & testService , & result1 )
memoryStore . Insert ( & testService2 , & result2 )
results := memoryStore . GetAll ( )
if len ( results ) != 2 {
t . Fatalf ( "MemoryStore should've returned 2 results, but actually returned %d" , len ( results ) )
}
key := fmt . Sprintf ( "%s_%s" , testService . Group , testService . Name )
serviceResults1 , exists := results [ key ]
if ! exists {
t . Fatalf ( "In Memory Store should've contained key '%s', but didn't" , key )
}
if len ( serviceResults1 . Results ) != 1 {
t . Fatalf ( "Service '%s' should've had 1 results, but actually returned %d" , serviceResults1 . Name , len ( serviceResults1 . Results ) )
}
key = fmt . Sprintf ( "%s_%s" , testService2 . Group , testService2 . Name )
serviceResults2 , exists := results [ key ]
if ! exists {
t . Fatalf ( "In Memory Store should've contained key '%s', but didn't" , key )
}
if len ( serviceResults2 . Results ) != 1 {
t . Fatalf ( "Service '%s' should've had 1 results, but actually returned %d" , serviceResults1 . Name , len ( serviceResults1 . Results ) )
}
}
func TestStorage_InsertResultForServiceWithErrorsIntoEmptyMemoryStore_ThenGetAllReturnsOneResultWithErrors ( t * testing . T ) {
memoryStore . Clear ( )
errors := [ ] string {
"error1" ,
"error2" ,
}
result1 := core . Result {
HTTPStatus : 404 ,
DNSRCode : "DNSRCode" ,
Body : nil ,
Hostname : "Hostname" ,
IP : "IP" ,
Connected : false ,
Duration : time . Second * 2 ,
Errors : errors ,
ConditionResults : nil ,
Success : false ,
Timestamp : time . Now ( ) ,
CertificateExpiration : time . Second * 2 ,
}
memoryStore . Insert ( & testService , & result1 )
results := memoryStore . GetAll ( )
if len ( results ) != 1 {
t . Fatalf ( "MemoryStore should've returned 1 results, but actually returned %d" , len ( results ) )
}
key := fmt . Sprintf ( "%s_%s" , testService . Group , testService . Name )
serviceResults , exists := results [ key ]
if ! exists {
t . Fatalf ( "In Memory Store should've contained key '%s', but didn't" , key )
}
if len ( serviceResults . Results ) != 1 {
t . Fatalf ( "Service '%s' should've had 2 results, but actually returned %d" , serviceResults . Name , len ( serviceResults . Results ) )
}
actualResult := serviceResults . Results [ 0 ]
if len ( actualResult . Errors ) != len ( errors ) {
t . Errorf ( "Service result should've had 2 errors, but actually had %d errors" , len ( actualResult . Errors ) )
}
for i , err := range actualResult . Errors {
if err != errors [ i ] {
t . Errorf ( "Error at index %d should've been %s, but was actually %s" , i , errors [ i ] , err )
}
}
}
func TestStorage_InsertResultForServiceWithConditionResultsIntoEmptyMemoryStore_ThenGetAllReturnsOneResultWithConditionResults ( t * testing . T ) {
memoryStore . Clear ( )
crs := [ ] * core . ConditionResult {
{
Condition : "condition1" ,
Success : true ,
} ,
{
Condition : "condition2" ,
Success : false ,
} ,
}
result := core . Result {
HTTPStatus : 404 ,
DNSRCode : "DNSRCode" ,
Body : nil ,
Hostname : "Hostname" ,
IP : "IP" ,
Connected : false ,
Duration : time . Second * 2 ,
Errors : nil ,
ConditionResults : crs ,
Success : false ,
Timestamp : time . Now ( ) ,
CertificateExpiration : time . Second * 2 ,
}
memoryStore . Insert ( & testService , & result )
results := memoryStore . GetAll ( )
if len ( results ) != 1 {
t . Fatalf ( "MemoryStore should've returned 1 results, but actually returned %d" , len ( results ) )
}
key := fmt . Sprintf ( "%s_%s" , testService . Group , testService . Name )
serviceResults , exists := results [ key ]
if ! exists {
t . Fatalf ( "In Memory Store should've contained key '%s', but didn't" , key )
}
if len ( serviceResults . Results ) != 1 {
t . Fatalf ( "Service '%s' should've had 2 results, but actually returned %d" , serviceResults . Name , len ( serviceResults . Results ) )
}
actualResult := serviceResults . Results [ 0 ]
if len ( actualResult . ConditionResults ) != len ( crs ) {
t . Errorf ( "Service result should've had 2 ConditionResults, but actually had %d ConditionResults" , len ( actualResult . Errors ) )
}
for i , cr := range actualResult . ConditionResults {
if cr . Condition != crs [ i ] . Condition {
t . Errorf ( "ConditionResult at index %d should've had condition %s, but was actually %s" , i , crs [ i ] . Condition , cr . Condition )
}
if cr . Success != crs [ i ] . Success {
t . Errorf ( "ConditionResult at index %d should've had success value of %t, but was actually %t" , i , crs [ i ] . Success , cr . Success )
}
}
}
2020-12-31 21:37:11 +01:00
func TestStorage_MultipleMemoryStoreInstancesReferToDifferentInternalMaps ( t * testing . T ) {
2020-12-30 11:57:17 +01:00
memoryStore . Clear ( )
currentMap := memoryStore . GetAll ( )
otherMemoryStore := NewInMemoryStore ( )
otherMemoryStoresMap := otherMemoryStore . GetAll ( )
if len ( currentMap ) != len ( otherMemoryStoresMap ) {
2020-12-31 21:37:11 +01:00
t . Errorf ( "Multiple memory stores should refer to the different internal maps, but 'memoryStore' returned %d results, and 'otherMemoryStore' returned %d results" , len ( currentMap ) , len ( otherMemoryStoresMap ) )
2020-12-30 11:57:17 +01:00
}
memoryStore . Insert ( & testService , & core . Result { } )
currentMap = memoryStore . GetAll ( )
otherMemoryStoresMap = otherMemoryStore . GetAll ( )
2020-12-31 21:37:11 +01:00
if len ( currentMap ) == len ( otherMemoryStoresMap ) {
t . Errorf ( "Multiple memory stores should refer to different internal maps, but 'memoryStore' returned %d results after inserting, and 'otherMemoryStore' returned %d results after inserting" , len ( currentMap ) , len ( otherMemoryStoresMap ) )
2020-12-30 11:57:17 +01:00
}
otherMemoryStore . Clear ( )
currentMap = memoryStore . GetAll ( )
otherMemoryStoresMap = otherMemoryStore . GetAll ( )
2020-12-31 21:37:11 +01:00
if len ( currentMap ) == len ( otherMemoryStoresMap ) {
t . Errorf ( "Multiple memory stores should refer to different internal maps, but 'memoryStore' returned %d results after clearing, and 'otherMemoryStore' returned %d results after clearing" , len ( currentMap ) , len ( otherMemoryStoresMap ) )
2020-12-30 11:57:17 +01:00
}
}
func TestStorage_ModificationsToReturnedMapDoNotAffectInternalMap ( t * testing . T ) {
memoryStore . Clear ( )
memoryStore . Insert ( & testService , & core . Result { } )
modifiedResults := memoryStore . GetAll ( )
for k := range modifiedResults {
delete ( modifiedResults , k )
}
results := memoryStore . GetAll ( )
if len ( modifiedResults ) == len ( results ) {
t . Errorf ( "Returned map from GetAll should be free to modify by the caller without affecting internal in-memory map, but length of results from in-memory map (%d) was equal to the length of results in modified map (%d)" , len ( results ) , len ( modifiedResults ) )
}
}
2020-12-31 21:43:11 +01:00
func TestStorage_GetServiceStatusForExistingStatusReturnsThatServiceStatus ( t * testing . T ) {
memoryStore . Clear ( )
memoryStore . Insert ( & testService , & core . Result { } )
serviceStatus := memoryStore . GetServiceStatus ( testService . Group , testService . Name )
if serviceStatus == nil {
t . Errorf ( "Returned service status for group '%s' and name '%s' was nil after inserting the service into the store" , testService . Group , testService . Name )
}
}
func TestStorage_GetServiceStatusForMissingStatusReturnsNil ( t * testing . T ) {
memoryStore . Clear ( )
memoryStore . Insert ( & testService , & core . Result { } )
serviceStatus := memoryStore . GetServiceStatus ( "nonexistantgroup" , "nonexistantname" )
if serviceStatus != nil {
t . Errorf ( "Returned service status for group '%s' and name '%s' not nil after inserting the service into the store" , testService . Group , testService . Name )
}
serviceStatus = memoryStore . GetServiceStatus ( testService . Group , "nonexistantname" )
if serviceStatus != nil {
t . Errorf ( "Returned service status for group '%s' and name '%s' not nil after inserting the service into the store" , testService . Group , "nonexistantname" )
}
serviceStatus = memoryStore . GetServiceStatus ( "nonexistantgroup" , testService . Name )
if serviceStatus != nil {
t . Errorf ( "Returned service status for group '%s' and name '%s' not nil after inserting the service into the store" , "nonexistantgroup" , testService . Name )
}
}