Repository: avenga/couper
Pull request #503 (2022-05-09 08:21:24)

Health expected status tuple
Change type of `expected_status` of `beta_health` block from `number` → `tuple`/`list`


Patch:
diff --git a/config/health_check.go b/config/health_check.go
index affde494..0629ebd2 100644
--- a/config/health_check.go
+++ b/config/health_check.go
@@ -35,7 +35,7 @@ type Health struct {
 	Interval         string   `hcl:"interval,optional"`
 	Timeout          string   `hcl:"timeout,optional"`
 	Path             string   `hcl:"path,optional"`
-	ExpectedStatus   int      `hcl:"expected_status,optional"`
+	ExpectedStatus   []int    `hcl:"expected_status,optional"`
 	ExpectedText     string   `hcl:"expected_text,optional"`
 	Headers          Headers  `hcl:"headers,optional"`
 	Remain           hcl.Body `hcl:",remain"`
@@ -66,8 +66,12 @@ func NewHealthCheck(baseURL string, options *Health, settings *Settings) (*Healt
 		if options.FailureThreshold != 0 {
 			healthCheck.FailureThreshold = options.FailureThreshold
 		}
-		if options.ExpectedStatus != 0 {
-			healthCheck.ExpectedStatus = map[int]bool{options.ExpectedStatus: true}
+		if len(options.ExpectedStatus) > 0 {
+			statusList := map[int]bool{}
+			for _, status := range options.ExpectedStatus {
+				statusList[status] = true
+			}
+			healthCheck.ExpectedStatus = statusList
 		}
 		healthCheck.ExpectedText = options.ExpectedText
 
diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md
index dfb591ad..f24a7451 100644
--- a/docs/REFERENCE.md
+++ b/docs/REFERENCE.md
@@ -546,10 +546,10 @@ via `headers` attribute.
 
 | Attributes          | Type                  | Default             | Description                                        | Characteristics       | Example                            |
 |:--------------------|:----------------------|:--------------------|:---------------------------------------------------|:----------------------|:-----------------------------------|
-| `expected_status`     | number                | `200`, `204`, `301` | wanted response status code                        |                       | `expected_status =  418`             |
-| `expected_text`       | string                | –                   | text response body must contain                    |                       | `expected_text = alive`              |
+| `expected_status`   | tuple (number)        | `[200, 204, 301]`   | wanted response status code                        |                       | `expected_status = [418]`          |
+| `expected_text`     | string                | –                   | text response body must contain                    |                       | `expected_text = "alive"`          |
 | `failure_threshold` | number                | `2`                 | failed checks needed to consider backend unhealthy |                       | `failure_threshold = 3`            |
-| `headers`           | object                | –                   | request headers                                    |                       | `headers = {User-Agent: "health"}` |
+| `headers`           | object                | –                   | request headers                                    |                       | `headers = {User-Agent = "health"}`|
 | `interval`          | [duration](#duration) | `"2s"`              | time interval for recheck                          |                       | `timeout = "5s"`                   |
 | `path`              | string                | –                   | URL path/query on backend host                     |                       | `path = "/health"`                 |
 | `timeout`           | [duration](#duration) | `"2s"`              | maximum allowed time limit                         | bounded by `interval` | `timeout = "3s"`                   |


Test patch:
diff --git a/config/configload/load_test.go b/config/configload/load_test.go
index 01cb8b63..a972582c 100644
--- a/config/configload/load_test.go
+++ b/config/configload/load_test.go
@@ -97,9 +97,9 @@ func TestHealthCheck(t *testing.T) {
 			"couper.hcl:13,29-30: Unsuitable value type; Unsuitable value: value must be a whole number, between 0 and 18446744073709551615 inclusive",
 		},
 		{
-			"Bad expect status",
-			`expected_status = [200, 204]`,
-			"couper.hcl:13,27-28: Unsuitable value type; Unsuitable value: number required",
+			"Bad expected status",
+			`expected_status = 200`,
+			"couper.hcl:13,27-30: Unsuitable value type; Unsuitable value: list of number required",
 		},
 		{
 			"OK",
@@ -107,7 +107,7 @@ func TestHealthCheck(t *testing.T) {
 			 timeout = "3s"
 			 interval = "5s"
 			 expected_text = 123
-			 expected_status = 200`,
+			 expected_status = [200, 418]`,
 			"",
 		},
 	}
diff --git a/handler/transport/backend_test.go b/handler/transport/backend_test.go
index e798b2e7..1ab1e8d2 100644
--- a/handler/transport/backend_test.go
+++ b/handler/transport/backend_test.go
@@ -396,7 +396,7 @@ func TestBackend_HealthCheck(t *testing.T) {
 				Interval:         "1h",
 				Timeout:          "9m",
 				Path:             "/gsund??",
-				ExpectedStatus:   418,
+				ExpectedStatus:   []int{418},
 				ExpectedText:     "roger roger",
 			},
 			expectation: expectation{
diff --git a/server/testdata/integration/config/14_couper.hcl b/server/testdata/integration/config/14_couper.hcl
index 7b976b6c..944b4b58 100644
--- a/server/testdata/integration/config/14_couper.hcl
+++ b/server/testdata/integration/config/14_couper.hcl
@@ -137,7 +137,7 @@ definitions {
   backend "healthy_expected_status" {
     origin = "${env.COUPER_TEST_BACKEND_ADDR}/not-there"
     beta_health {
-      expected_status = 404
+      expected_status = [404]
     }
   }
   backend "healthy_expected_text" {
@@ -175,7 +175,7 @@ definitions {
     origin = env.COUPER_TEST_BACKEND_ADDR
     beta_health {
       path = "/redirect?url=/health?redirected"
-      expected_status = 302
+      expected_status = [302]
     }
   }
   backend "unhealthy_timeout" {
@@ -189,7 +189,7 @@ definitions {
   backend "unhealthy_bad_expected_status" {
     origin = "${env.COUPER_TEST_BACKEND_ADDR}/health"
     beta_health {
-      expected_status = 500
+      expected_status = [500]
     }
   }
   backend "unhealthy_bad_expected_text" {