Merge pull request #41 from Exagone313/basic-duration-string
Add basic duration comparison
This commit is contained in:
@ -157,6 +157,7 @@ Here are some examples of conditions you can use:
|
|||||||
| `len([BODY].data) < 5` | Array at JSONPath `$.data` has less than 5 elements | `{"data":[{"id":1}]}` | |
|
| `len([BODY].data) < 5` | Array at JSONPath `$.data` has less than 5 elements | `{"data":[{"id":1}]}` | |
|
||||||
| `len([BODY].name) == 8` | String at JSONPath `$.name` has a length of 8 | `{"name":"john.doe"}` | `{"name":"bob"}` |
|
| `len([BODY].name) == 8` | String at JSONPath `$.name` has a length of 8 | `{"name":"john.doe"}` | `{"name":"bob"}` |
|
||||||
| `[BODY].name == pat(john*)` | String at JSONPath `$.name` matches pattern `john*` | `{"name":"john.doe"}` | `{"name":"bob"}` |
|
| `[BODY].name == pat(john*)` | String at JSONPath `$.name` matches pattern `john*` | `{"name":"john.doe"}` | `{"name":"bob"}` |
|
||||||
|
| `[CERTIFICATE_EXPIRATION] > 48h` | Certificate expiration is more than 48h away | `{"name":"john.doe"}` | `{"name":"bob"}` |
|
||||||
|
|
||||||
|
|
||||||
#### Placeholders
|
#### Placeholders
|
||||||
@ -168,7 +169,7 @@ Here are some examples of conditions you can use:
|
|||||||
| `[IP]` | Resolves into the IP of the target host | 192.168.0.232
|
| `[IP]` | Resolves into the IP of the target host | 192.168.0.232
|
||||||
| `[BODY]` | Resolves into the response body. Supports JSONPath. | `{"name":"john.doe"}`
|
| `[BODY]` | Resolves into the response body. Supports JSONPath. | `{"name":"john.doe"}`
|
||||||
| `[CONNECTED]` | Resolves into whether a connection could be established | `true`
|
| `[CONNECTED]` | Resolves into whether a connection could be established | `true`
|
||||||
| `[CERTIFICATE_EXPIRATION]` | Resolves into the duration before certificate expiration, in ms | 4461677039, 0 (if not using HTTPS)
|
| `[CERTIFICATE_EXPIRATION]` | Resolves into the duration before certificate expiration | `24h`, `48h`, 0 (if not using HTTPS)
|
||||||
|
|
||||||
|
|
||||||
#### Functions
|
#### Functions
|
||||||
|
@ -2,11 +2,13 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/TwinProduction/gatus/jsonpath"
|
|
||||||
"github.com/TwinProduction/gatus/pattern"
|
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/TwinProduction/gatus/jsonpath"
|
||||||
|
"github.com/TwinProduction/gatus/pattern"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -185,7 +187,9 @@ func sanitizeAndResolveNumerical(list []string, result *Result) []int64 {
|
|||||||
var sanitizedNumbers []int64
|
var sanitizedNumbers []int64
|
||||||
sanitizedList := sanitizeAndResolve(list, result)
|
sanitizedList := sanitizeAndResolve(list, result)
|
||||||
for _, element := range sanitizedList {
|
for _, element := range sanitizedList {
|
||||||
if number, err := strconv.ParseInt(element, 10, 64); err != nil {
|
if duration, err := time.ParseDuration(element); duration != 0 && err == nil {
|
||||||
|
sanitizedNumbers = append(sanitizedNumbers, duration.Milliseconds())
|
||||||
|
} else if number, err := strconv.ParseInt(element, 10, 64); err != nil {
|
||||||
// Default to 0 if the string couldn't be converted to an integer
|
// Default to 0 if the string couldn't be converted to an integer
|
||||||
sanitizedNumbers = append(sanitizedNumbers, 0)
|
sanitizedNumbers = append(sanitizedNumbers, 0)
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,7 +60,27 @@ func TestCondition_evaluateWithResponseTimeUsingLessThan(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCondition_evaluateWithResponseTimeUsingLessThanDuration(t *testing.T) {
|
||||||
|
condition := Condition("[RESPONSE_TIME] < 1s")
|
||||||
|
result := &Result{Duration: time.Millisecond * 50}
|
||||||
|
condition.evaluate(result)
|
||||||
|
if !result.ConditionResults[0].Success {
|
||||||
|
t.Errorf("Condition '%s' should have been a success", condition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCondition_evaluateWithResponseTimeUsingLessThanInvalid(t *testing.T) {
|
||||||
|
condition := Condition("[RESPONSE_TIME] < potato")
|
||||||
|
result := &Result{Duration: time.Millisecond * 50}
|
||||||
|
condition.evaluate(result)
|
||||||
|
if result.ConditionResults[0].Success {
|
||||||
|
t.Errorf("Condition '%s' should have failed because the condition has an invalid numerical value that should've automatically resolved to 0", condition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCondition_evaluateWithResponseTimeUsingGreaterThan(t *testing.T) {
|
func TestCondition_evaluateWithResponseTimeUsingGreaterThan(t *testing.T) {
|
||||||
|
// Not exactly sure why you'd want to have a condition that checks if the response time is too fast,
|
||||||
|
// but hey, who am I to judge?
|
||||||
condition := Condition("[RESPONSE_TIME] > 500")
|
condition := Condition("[RESPONSE_TIME] > 500")
|
||||||
result := &Result{Duration: time.Millisecond * 750}
|
result := &Result{Duration: time.Millisecond * 750}
|
||||||
condition.evaluate(result)
|
condition.evaluate(result)
|
||||||
@ -69,6 +89,15 @@ func TestCondition_evaluateWithResponseTimeUsingGreaterThan(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCondition_evaluateWithResponseTimeUsingGreaterThanDuration(t *testing.T) {
|
||||||
|
condition := Condition("[RESPONSE_TIME] > 1s")
|
||||||
|
result := &Result{Duration: time.Second * 2}
|
||||||
|
condition.evaluate(result)
|
||||||
|
if !result.ConditionResults[0].Success {
|
||||||
|
t.Errorf("Condition '%s' should have been a success", condition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestCondition_evaluateWithResponseTimeUsingGreaterThanOrEqualTo(t *testing.T) {
|
func TestCondition_evaluateWithResponseTimeUsingGreaterThanOrEqualTo(t *testing.T) {
|
||||||
condition := Condition("[RESPONSE_TIME] >= 500")
|
condition := Condition("[RESPONSE_TIME] >= 500")
|
||||||
result := &Result{Duration: time.Millisecond * 500}
|
result := &Result{Duration: time.Millisecond * 500}
|
||||||
@ -320,7 +349,7 @@ func TestCondition_evaluateWithUnsetCertificateExpiration(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCondition_evaluateWithCertificateExpirationGreaterThan(t *testing.T) {
|
func TestCondition_evaluateWithCertificateExpirationGreaterThanNumerical(t *testing.T) {
|
||||||
acceptable := (time.Hour * 24 * 28).Milliseconds()
|
acceptable := (time.Hour * 24 * 28).Milliseconds()
|
||||||
condition := Condition("[CERTIFICATE_EXPIRATION] > " + strconv.FormatInt(acceptable, 10))
|
condition := Condition("[CERTIFICATE_EXPIRATION] > " + strconv.FormatInt(acceptable, 10))
|
||||||
result := &Result{CertificateExpiration: time.Hour * 24 * 60}
|
result := &Result{CertificateExpiration: time.Hour * 24 * 60}
|
||||||
@ -330,7 +359,7 @@ func TestCondition_evaluateWithCertificateExpirationGreaterThan(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCondition_evaluateWithCertificateExpirationGreaterThanFailure(t *testing.T) {
|
func TestCondition_evaluateWithCertificateExpirationGreaterThanNumericalFailure(t *testing.T) {
|
||||||
acceptable := (time.Hour * 24 * 28).Milliseconds()
|
acceptable := (time.Hour * 24 * 28).Milliseconds()
|
||||||
condition := Condition("[CERTIFICATE_EXPIRATION] > " + strconv.FormatInt(acceptable, 10))
|
condition := Condition("[CERTIFICATE_EXPIRATION] > " + strconv.FormatInt(acceptable, 10))
|
||||||
result := &Result{CertificateExpiration: time.Hour * 24 * 14}
|
result := &Result{CertificateExpiration: time.Hour * 24 * 14}
|
||||||
@ -339,3 +368,21 @@ func TestCondition_evaluateWithCertificateExpirationGreaterThanFailure(t *testin
|
|||||||
t.Errorf("Condition '%s' should have been a failure", condition)
|
t.Errorf("Condition '%s' should have been a failure", condition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCondition_evaluateWithCertificateExpirationGreaterThanDuration(t *testing.T) {
|
||||||
|
condition := Condition("[CERTIFICATE_EXPIRATION] > 12h")
|
||||||
|
result := &Result{CertificateExpiration: 24 * time.Hour}
|
||||||
|
condition.evaluate(result)
|
||||||
|
if !result.ConditionResults[0].Success {
|
||||||
|
t.Errorf("Condition '%s' should have been a success", condition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCondition_evaluateWithCertificateExpirationGreaterThanDurationFailure(t *testing.T) {
|
||||||
|
condition := Condition("[CERTIFICATE_EXPIRATION] > 48h")
|
||||||
|
result := &Result{CertificateExpiration: 24 * time.Hour}
|
||||||
|
condition.evaluate(result)
|
||||||
|
if result.ConditionResults[0].Success {
|
||||||
|
t.Errorf("Condition '%s' should have been a failure", condition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user