package core import ( "strconv" "testing" "time" ) func TestCondition_evaluate(t *testing.T) { type scenario struct { Name string Condition Condition Result *Result DontResolveFailedConditions bool ExpectedSuccess bool ExpectedOutput string } scenarios := []scenario{ { Name: "ip", Condition: Condition("[IP] == 127.0.0.1"), Result: &Result{IP: "127.0.0.1"}, ExpectedSuccess: true, ExpectedOutput: "[IP] == 127.0.0.1", }, { Name: "status", Condition: Condition("[STATUS] == 200"), Result: &Result{HTTPStatus: 200}, ExpectedSuccess: true, ExpectedOutput: "[STATUS] == 200", }, { Name: "status-failure", Condition: Condition("[STATUS] == 200"), Result: &Result{HTTPStatus: 500}, ExpectedSuccess: false, ExpectedOutput: "[STATUS] (500) == 200", }, { Name: "status-using-less-than", Condition: Condition("[STATUS] < 300"), Result: &Result{HTTPStatus: 201}, ExpectedSuccess: true, ExpectedOutput: "[STATUS] < 300", }, { Name: "status-using-less-than-failure", Condition: Condition("[STATUS] < 300"), Result: &Result{HTTPStatus: 404}, ExpectedSuccess: false, ExpectedOutput: "[STATUS] (404) < 300", }, { Name: "response-time-using-less-than", Condition: Condition("[RESPONSE_TIME] < 500"), Result: &Result{Duration: 50 * time.Millisecond}, ExpectedSuccess: true, ExpectedOutput: "[RESPONSE_TIME] < 500", }, { Name: "response-time-using-less-than-with-duration", Condition: Condition("[RESPONSE_TIME] < 1s"), Result: &Result{Duration: 50 * time.Millisecond}, ExpectedSuccess: true, ExpectedOutput: "[RESPONSE_TIME] < 1s", }, { Name: "response-time-using-less-than-invalid", Condition: Condition("[RESPONSE_TIME] < potato"), Result: &Result{Duration: 50 * time.Millisecond}, ExpectedSuccess: false, ExpectedOutput: "[RESPONSE_TIME] (50) < potato (0)", // Non-numerical values automatically resolve to 0 }, { Name: "response-time-using-greater-than", Condition: Condition("[RESPONSE_TIME] > 500"), Result: &Result{Duration: 750 * time.Millisecond}, ExpectedSuccess: true, ExpectedOutput: "[RESPONSE_TIME] > 500", }, { Name: "response-time-using-greater-than-with-duration", Condition: Condition("[RESPONSE_TIME] > 1s"), Result: &Result{Duration: 2 * time.Second}, ExpectedSuccess: true, ExpectedOutput: "[RESPONSE_TIME] > 1s", }, { Name: "response-time-using-greater-than-or-equal-to-equal", Condition: Condition("[RESPONSE_TIME] >= 500"), Result: &Result{Duration: 500 * time.Millisecond}, ExpectedSuccess: true, ExpectedOutput: "[RESPONSE_TIME] >= 500", }, { Name: "response-time-using-greater-than-or-equal-to-greater", Condition: Condition("[RESPONSE_TIME] >= 500"), Result: &Result{Duration: 499 * time.Millisecond}, ExpectedSuccess: false, ExpectedOutput: "[RESPONSE_TIME] (499) >= 500", }, { Name: "response-time-using-greater-than-or-equal-to-failure", Condition: Condition("[RESPONSE_TIME] >= 500"), Result: &Result{Duration: 499 * time.Millisecond}, ExpectedSuccess: false, ExpectedOutput: "[RESPONSE_TIME] (499) >= 500", }, { Name: "response-time-using-less-than-or-equal-to-equal", Condition: Condition("[RESPONSE_TIME] <= 500"), Result: &Result{Duration: 500 * time.Millisecond}, ExpectedSuccess: true, ExpectedOutput: "[RESPONSE_TIME] <= 500", }, { Name: "response-time-using-less-than-or-equal-to-less", Condition: Condition("[RESPONSE_TIME] <= 500"), Result: &Result{Duration: 25 * time.Millisecond}, ExpectedSuccess: true, ExpectedOutput: "[RESPONSE_TIME] <= 500", }, { Name: "response-time-using-less-than-or-equal-to-failure", Condition: Condition("[RESPONSE_TIME] <= 500"), Result: &Result{Duration: 750 * time.Millisecond}, ExpectedSuccess: false, ExpectedOutput: "[RESPONSE_TIME] (750) <= 500", }, { Name: "body", Condition: Condition("[BODY] == test"), Result: &Result{body: []byte("test")}, ExpectedSuccess: true, ExpectedOutput: "[BODY] == test", }, { Name: "body-jsonpath", Condition: Condition("[BODY].status == UP"), Result: &Result{body: []byte("{\"status\":\"UP\"}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY].status == UP", }, { Name: "body-jsonpath-complex", Condition: Condition("[BODY].data.name == john"), Result: &Result{body: []byte("{\"data\": {\"id\": 1, \"name\": \"john\"}}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY].data.name == john", }, { Name: "body-jsonpath-complex-invalid", Condition: Condition("[BODY].data.name == john"), Result: &Result{body: []byte("{\"data\": {\"id\": 1}}")}, ExpectedSuccess: false, ExpectedOutput: "[BODY].data.name (INVALID) == john", }, { Name: "body-jsonpath-complex-len", Condition: Condition("len([BODY].data.name) == 4"), Result: &Result{body: []byte("{\"data\": {\"name\": \"john\"}}")}, ExpectedSuccess: true, ExpectedOutput: "len([BODY].data.name) == 4", }, { Name: "body-jsonpath-complex-len-invalid", Condition: Condition("len([BODY].data.name) == john"), Result: &Result{body: []byte("{\"data\": {\"id\": 1}}")}, ExpectedSuccess: false, ExpectedOutput: "len([BODY].data.name) (INVALID) == john", }, { Name: "body-jsonpath-double-placeholder", Condition: Condition("[BODY].user.firstName != [BODY].user.lastName"), Result: &Result{body: []byte("{\"user\": {\"firstName\": \"john\", \"lastName\": \"doe\"}}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY].user.firstName != [BODY].user.lastName", }, { Name: "body-jsonpath-double-placeholder-failure", Condition: Condition("[BODY].user.firstName == [BODY].user.lastName"), Result: &Result{body: []byte("{\"user\": {\"firstName\": \"john\", \"lastName\": \"doe\"}}")}, ExpectedSuccess: false, ExpectedOutput: "[BODY].user.firstName (john) == [BODY].user.lastName (doe)", }, { Name: "body-jsonpath-when-body-is-array", Condition: Condition("[BODY][0].id == 1"), Result: &Result{body: []byte("[{\"id\": 1}, {\"id\": 2}]")}, ExpectedSuccess: true, ExpectedOutput: "[BODY][0].id == 1", }, { Name: "body-jsonpath-complex-int", Condition: Condition("[BODY].data.id == 1"), Result: &Result{body: []byte("{\"data\": {\"id\": 1}}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY].data.id == 1", }, { Name: "body-jsonpath-complex-array-int", Condition: Condition("[BODY].data[1].id == 2"), Result: &Result{body: []byte("{\"data\": [{\"id\": 1}, {\"id\": 2}, {\"id\": 3}]}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY].data[1].id == 2", }, { Name: "body-jsonpath-complex-int-using-greater-than", Condition: Condition("[BODY].data.id > 0"), Result: &Result{body: []byte("{\"data\": {\"id\": 1}}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY].data.id > 0", }, { Name: "body-jsonpath-complex-int-using-greater-than-failure", Condition: Condition("[BODY].data.id > 5"), Result: &Result{body: []byte("{\"data\": {\"id\": 1}}")}, ExpectedSuccess: false, ExpectedOutput: "[BODY].data.id (1) > 5", }, { Name: "body-jsonpath-complex-int-using-less-than", Condition: Condition("[BODY].data.id < 5"), Result: &Result{body: []byte("{\"data\": {\"id\": 2}}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY].data.id < 5", }, { Name: "body-jsonpath-complex-int-using-less-than-failure", Condition: Condition("[BODY].data.id < 5"), Result: &Result{body: []byte("{\"data\": {\"id\": 10}}")}, ExpectedSuccess: false, ExpectedOutput: "[BODY].data.id (10) < 5", }, { Name: "body-len-array", Condition: Condition("len([BODY].data) == 3"), Result: &Result{body: []byte("{\"data\": [{\"id\": 1}, {\"id\": 2}, {\"id\": 3}]}")}, ExpectedSuccess: true, ExpectedOutput: "len([BODY].data) == 3", }, { Name: "body-len-array-invalid", Condition: Condition("len([BODY].data) == 8"), Result: &Result{body: []byte("{\"name\": \"john.doe\"}")}, ExpectedSuccess: false, ExpectedOutput: "len([BODY].data) (INVALID) == 8", }, { Name: "body-len-string", Condition: Condition("len([BODY].name) == 8"), Result: &Result{body: []byte("{\"name\": \"john.doe\"}")}, ExpectedSuccess: true, ExpectedOutput: "len([BODY].name) == 8", }, { Name: "body-pattern", Condition: Condition("[BODY] == pat(*john*)"), Result: &Result{body: []byte("{\"name\": \"john.doe\"}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY] == pat(*john*)", }, { Name: "body-pattern-2", Condition: Condition("[BODY].name == pat(john*)"), Result: &Result{body: []byte("{\"name\": \"john.doe\"}")}, ExpectedSuccess: true, ExpectedOutput: "[BODY].name == pat(john*)", }, { Name: "body-pattern-failure", Condition: Condition("[BODY].name == pat(bob*)"), Result: &Result{body: []byte("{\"name\": \"john.doe\"}")}, ExpectedSuccess: false, ExpectedOutput: "[BODY].name (john.doe) == pat(bob*)", }, { Name: "body-pattern-html", Condition: Condition("[BODY] == pat(*