2017-03-09 16:27:31 +01:00
package healthcheck
import (
"context"
"net/http"
"net/http/httptest"
"net/url"
"sync"
"testing"
"time"
2018-04-16 11:40:03 +02:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2020-09-16 15:46:04 +02:00
"github.com/traefik/traefik/v2/pkg/config/runtime"
"github.com/traefik/traefik/v2/pkg/testhelpers"
2022-12-05 11:30:05 +01:00
"github.com/vulcand/oxy/v2/roundrobin"
2017-03-09 16:27:31 +01:00
)
2020-07-07 14:42:03 +02:00
const (
healthCheckInterval = 200 * time . Millisecond
healthCheckTimeout = 100 * time . Millisecond
)
2017-03-09 16:27:31 +01:00
2023-11-17 01:50:06 +01:00
const delta float64 = 1e-10
2017-03-09 16:27:31 +01:00
type testHandler struct {
done func ( )
2018-05-22 09:22:03 +02:00
healthSequence [ ] int
2017-03-09 16:27:31 +01:00
}
func TestSetBackendsConfiguration ( t * testing . T ) {
2018-04-16 11:40:03 +02:00
testCases := [ ] struct {
desc string
startHealthy bool
2018-05-22 09:22:03 +02:00
healthSequence [ ] int
2018-04-16 11:40:03 +02:00
expectedNumRemovedServers int
expectedNumUpsertedServers int
expectedGaugeValue float64
2017-03-09 16:27:31 +01:00
} {
{
2018-04-16 11:40:03 +02:00
desc : "healthy server staying healthy" ,
startHealthy : true ,
2018-05-22 09:22:03 +02:00
healthSequence : [ ] int { http . StatusOK } ,
expectedNumRemovedServers : 0 ,
expectedNumUpsertedServers : 0 ,
expectedGaugeValue : 1 ,
} ,
{
desc : "healthy server staying healthy (StatusNoContent)" ,
startHealthy : true ,
healthSequence : [ ] int { http . StatusNoContent } ,
2018-04-16 11:40:03 +02:00
expectedNumRemovedServers : 0 ,
expectedNumUpsertedServers : 0 ,
expectedGaugeValue : 1 ,
2017-03-09 16:27:31 +01:00
} ,
2018-05-23 17:06:04 +02:00
{
desc : "healthy server staying healthy (StatusPermanentRedirect)" ,
startHealthy : true ,
healthSequence : [ ] int { http . StatusPermanentRedirect } ,
expectedNumRemovedServers : 0 ,
expectedNumUpsertedServers : 0 ,
expectedGaugeValue : 1 ,
} ,
2017-03-09 16:27:31 +01:00
{
2018-04-16 11:40:03 +02:00
desc : "healthy server becoming sick" ,
startHealthy : true ,
2018-05-22 09:22:03 +02:00
healthSequence : [ ] int { http . StatusServiceUnavailable } ,
2018-04-16 11:40:03 +02:00
expectedNumRemovedServers : 1 ,
expectedNumUpsertedServers : 0 ,
expectedGaugeValue : 0 ,
2017-03-09 16:27:31 +01:00
} ,
{
2018-04-16 11:40:03 +02:00
desc : "sick server becoming healthy" ,
startHealthy : false ,
2018-05-22 09:22:03 +02:00
healthSequence : [ ] int { http . StatusOK } ,
2018-04-16 11:40:03 +02:00
expectedNumRemovedServers : 0 ,
expectedNumUpsertedServers : 1 ,
expectedGaugeValue : 1 ,
2017-03-09 16:27:31 +01:00
} ,
{
2018-04-16 11:40:03 +02:00
desc : "sick server staying sick" ,
startHealthy : false ,
2018-05-22 09:22:03 +02:00
healthSequence : [ ] int { http . StatusServiceUnavailable } ,
2018-04-16 11:40:03 +02:00
expectedNumRemovedServers : 0 ,
expectedNumUpsertedServers : 0 ,
expectedGaugeValue : 0 ,
2017-03-09 16:27:31 +01:00
} ,
{
2018-04-16 11:40:03 +02:00
desc : "healthy server toggling to sick and back to healthy" ,
startHealthy : true ,
2018-05-22 09:22:03 +02:00
healthSequence : [ ] int { http . StatusServiceUnavailable , http . StatusOK } ,
2018-04-16 11:40:03 +02:00
expectedNumRemovedServers : 1 ,
expectedNumUpsertedServers : 1 ,
expectedGaugeValue : 1 ,
2017-03-09 16:27:31 +01:00
} ,
}
2018-04-16 11:40:03 +02:00
for _ , test := range testCases {
2017-03-09 16:27:31 +01:00
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
2018-05-22 09:22:03 +02:00
2018-08-06 20:00:03 +02:00
// The context is passed to the health check and canonically canceled by
2017-03-09 16:27:31 +01:00
// the test server once all expected requests have been received.
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
ts := newTestServer ( cancel , test . healthSequence )
defer ts . Close ( )
lb := & testLoadBalancer { RWMutex : & sync . RWMutex { } }
2018-06-11 11:36:03 +02:00
backend := NewBackendConfig ( Options {
2017-03-15 19:16:06 +01:00
Path : "/path" ,
Interval : healthCheckInterval ,
2018-09-27 13:16:03 -05:00
Timeout : healthCheckTimeout ,
2017-03-15 19:16:06 +01:00
LB : lb ,
2018-01-03 12:32:03 +01:00
} , "backendName" )
2018-04-16 11:40:03 +02:00
2017-06-03 15:02:28 +02:00
serverURL := testhelpers . MustParseURL ( ts . URL )
2017-03-09 16:27:31 +01:00
if test . startHealthy {
lb . servers = append ( lb . servers , serverURL )
} else {
2019-08-07 08:14:04 -07:00
backend . disabledURLs = append ( backend . disabledURLs , backendURL { url : serverURL , weight : 1 } )
2017-03-09 16:27:31 +01:00
}
2020-09-26 13:30:03 +02:00
collectingMetrics := & testhelpers . CollectingGauge { }
2017-06-03 15:02:28 +02:00
check := HealthCheck {
2018-06-11 11:36:03 +02:00
Backends : make ( map [ string ] * BackendConfig ) ,
2020-09-26 13:30:03 +02:00
metrics : metricsHealthcheck { serverUpGauge : collectingMetrics } ,
2017-03-09 16:27:31 +01:00
}
2018-04-16 11:40:03 +02:00
2017-03-09 16:27:31 +01:00
wg := sync . WaitGroup { }
wg . Add ( 1 )
2018-04-16 11:40:03 +02:00
2017-03-09 16:27:31 +01:00
go func ( ) {
2018-01-03 12:32:03 +01:00
check . execute ( ctx , backend )
2017-03-09 16:27:31 +01:00
wg . Done ( )
} ( )
// Make test timeout dependent on number of expected requests, health
// check interval, and a safety margin.
timeout := time . Duration ( len ( test . healthSequence ) * int ( healthCheckInterval ) + 500 )
select {
case <- time . After ( timeout ) :
t . Fatal ( "test did not complete in time" )
case <- ctx . Done ( ) :
wg . Wait ( )
}
lb . Lock ( )
defer lb . Unlock ( )
2018-01-26 11:58:03 +01:00
2018-04-16 11:40:03 +02:00
assert . Equal ( t , test . expectedNumRemovedServers , lb . numRemovedServers , "removed servers" )
assert . Equal ( t , test . expectedNumUpsertedServers , lb . numUpsertedServers , "upserted servers" )
2023-11-17 01:50:06 +01:00
assert . InDelta ( t , test . expectedGaugeValue , collectingMetrics . GaugeValue , delta , "ServerUp Gauge" )
2017-03-09 16:27:31 +01:00
} )
}
}
2017-05-10 14:28:57 -04:00
func TestNewRequest ( t * testing . T ) {
2018-11-15 15:50:03 +01:00
type expected struct {
err bool
value string
}
2018-04-16 11:40:03 +02:00
testCases := [ ] struct {
2018-05-14 12:08:03 +02:00
desc string
serverURL string
options Options
2018-11-15 15:50:03 +01:00
expected expected
2017-05-10 14:28:57 -04:00
} {
{
2018-05-14 12:08:03 +02:00
desc : "no port override" ,
serverURL : "http://backend1:80" ,
options : Options {
Path : "/test" ,
Port : 0 ,
} ,
2018-11-15 15:50:03 +01:00
expected : expected {
err : false ,
value : "http://backend1:80/test" ,
} ,
2017-05-10 14:28:57 -04:00
} ,
{
2018-05-14 12:08:03 +02:00
desc : "port override" ,
serverURL : "http://backend2:80" ,
options : Options {
Path : "/test" ,
Port : 8080 ,
} ,
2018-11-15 15:50:03 +01:00
expected : expected {
err : false ,
value : "http://backend2:8080/test" ,
} ,
2017-05-10 14:28:57 -04:00
} ,
{
2018-05-14 12:08:03 +02:00
desc : "no port override with no port in server URL" ,
serverURL : "http://backend1" ,
options : Options {
Path : "/health" ,
Port : 0 ,
} ,
2018-11-15 15:50:03 +01:00
expected : expected {
err : false ,
value : "http://backend1/health" ,
} ,
2017-05-10 14:28:57 -04:00
} ,
{
2018-05-14 12:08:03 +02:00
desc : "port override with no port in server URL" ,
serverURL : "http://backend2" ,
options : Options {
Path : "/health" ,
Port : 8080 ,
} ,
2018-11-15 15:50:03 +01:00
expected : expected {
err : false ,
value : "http://backend2:8080/health" ,
} ,
2017-05-10 14:28:57 -04:00
} ,
2018-05-14 12:08:03 +02:00
{
desc : "scheme override" ,
serverURL : "https://backend1:80" ,
options : Options {
Scheme : "http" ,
Path : "/test" ,
Port : 0 ,
} ,
2018-11-15 15:50:03 +01:00
expected : expected {
err : false ,
value : "http://backend1:80/test" ,
} ,
} ,
{
desc : "path with param" ,
serverURL : "http://backend1:80" ,
options : Options {
Path : "/health?powpow=do" ,
Port : 0 ,
} ,
expected : expected {
err : false ,
value : "http://backend1:80/health?powpow=do" ,
} ,
} ,
{
desc : "path with params" ,
serverURL : "http://backend1:80" ,
options : Options {
Path : "/health?powpow=do&do=powpow" ,
Port : 0 ,
} ,
expected : expected {
err : false ,
value : "http://backend1:80/health?powpow=do&do=powpow" ,
} ,
} ,
{
desc : "path with invalid path" ,
serverURL : "http://backend1:80" ,
options : Options {
Path : ":" ,
Port : 0 ,
} ,
expected : expected {
err : true ,
value : "" ,
} ,
2018-05-14 12:08:03 +02:00
} ,
2017-05-10 14:28:57 -04:00
}
2018-04-16 11:40:03 +02:00
for _ , test := range testCases {
2017-05-10 14:28:57 -04:00
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
2018-04-16 11:40:03 +02:00
2018-06-11 11:36:03 +02:00
backend := NewBackendConfig ( test . options , "backendName" )
2017-05-10 14:28:57 -04:00
2018-11-15 15:50:03 +01:00
u := testhelpers . MustParseURL ( test . serverURL )
2017-05-10 14:28:57 -04:00
2018-04-16 11:40:03 +02:00
req , err := backend . newRequest ( u )
2018-11-15 15:50:03 +01:00
if test . expected . err {
require . Error ( t , err )
assert . Nil ( t , nil )
} else {
require . NoError ( t , err , "failed to create new backend request" )
require . NotNil ( t , req )
assert . Equal ( t , test . expected . value , req . URL . String ( ) )
}
2018-04-16 11:40:03 +02:00
} )
}
}
2022-08-08 10:22:07 -03:00
func TestRequestOptions ( t * testing . T ) {
2018-04-16 11:40:03 +02:00
testCases := [ ] struct {
desc string
2018-05-14 12:08:03 +02:00
serverURL string
options Options
2018-04-16 11:40:03 +02:00
expectedHostname string
expectedHeader string
2022-08-08 10:22:07 -03:00
expectedMethod string
2018-04-16 11:40:03 +02:00
} {
{
2018-05-14 12:08:03 +02:00
desc : "override hostname" ,
serverURL : "http://backend1:80" ,
options : Options {
Hostname : "myhost" ,
Path : "/" ,
} ,
2018-04-16 11:40:03 +02:00
expectedHostname : "myhost" ,
expectedHeader : "" ,
2022-08-08 10:22:07 -03:00
expectedMethod : http . MethodGet ,
2018-04-16 11:40:03 +02:00
} ,
{
2018-05-14 12:08:03 +02:00
desc : "not override hostname" ,
serverURL : "http://backend1:80" ,
options : Options {
Hostname : "" ,
Path : "/" ,
} ,
2018-04-16 11:40:03 +02:00
expectedHostname : "backend1:80" ,
expectedHeader : "" ,
2022-08-08 10:22:07 -03:00
expectedMethod : http . MethodGet ,
2018-04-16 11:40:03 +02:00
} ,
{
2018-05-14 12:08:03 +02:00
desc : "custom header" ,
serverURL : "http://backend1:80" ,
options : Options {
Headers : map [ string ] string { "Custom-Header" : "foo" } ,
Hostname : "" ,
Path : "/" ,
} ,
2018-04-16 11:40:03 +02:00
expectedHostname : "backend1:80" ,
expectedHeader : "foo" ,
2022-08-08 10:22:07 -03:00
expectedMethod : http . MethodGet ,
2018-04-16 11:40:03 +02:00
} ,
{
2018-05-14 12:08:03 +02:00
desc : "custom header with hostname override" ,
serverURL : "http://backend1:80" ,
options : Options {
Headers : map [ string ] string { "Custom-Header" : "foo" } ,
Hostname : "myhost" ,
Path : "/" ,
} ,
2018-04-16 11:40:03 +02:00
expectedHostname : "myhost" ,
expectedHeader : "foo" ,
2022-08-08 10:22:07 -03:00
expectedMethod : http . MethodGet ,
} ,
{
desc : "custom method" ,
serverURL : "http://backend1:80" ,
options : Options {
Path : "/" ,
Method : http . MethodHead ,
} ,
expectedHostname : "backend1:80" ,
expectedMethod : http . MethodHead ,
2018-04-16 11:40:03 +02:00
} ,
}
for _ , test := range testCases {
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
2018-06-11 11:36:03 +02:00
backend := NewBackendConfig ( test . options , "backendName" )
2018-04-16 11:40:03 +02:00
2018-05-14 12:08:03 +02:00
u , err := url . Parse ( test . serverURL )
require . NoError ( t , err )
2018-04-16 11:40:03 +02:00
2017-05-10 14:28:57 -04:00
req , err := backend . newRequest ( u )
2018-05-14 12:08:03 +02:00
require . NoError ( t , err , "failed to create new backend request" )
2017-05-10 14:28:57 -04:00
2022-08-08 10:22:07 -03:00
req = backend . setRequestOptions ( req )
2018-04-16 11:40:03 +02:00
2018-05-14 12:08:03 +02:00
assert . Equal ( t , "http://backend1:80/" , req . URL . String ( ) )
2018-04-16 11:40:03 +02:00
assert . Equal ( t , test . expectedHostname , req . Host )
assert . Equal ( t , test . expectedHeader , req . Header . Get ( "Custom-Header" ) )
2022-08-08 10:22:07 -03:00
assert . Equal ( t , test . expectedMethod , req . Method )
2017-05-10 14:28:57 -04:00
} )
}
2017-06-03 15:02:28 +02:00
}
2022-06-22 21:46:08 +02:00
func TestBalancers_Servers ( t * testing . T ) {
server1 , err := url . Parse ( "http://foo.com" )
require . NoError ( t , err )
balancer1 , err := roundrobin . New ( nil )
require . NoError ( t , err )
err = balancer1 . UpsertServer ( server1 )
require . NoError ( t , err )
server2 , err := url . Parse ( "http://foo.com" )
require . NoError ( t , err )
balancer2 , err := roundrobin . New ( nil )
require . NoError ( t , err )
err = balancer2 . UpsertServer ( server2 )
require . NoError ( t , err )
balancers := Balancers ( [ ] Balancer { balancer1 , balancer2 } )
want , err := url . Parse ( "http://foo.com" )
require . NoError ( t , err )
2023-11-17 01:50:06 +01:00
assert . Len ( t , balancers . Servers ( ) , 1 )
2022-06-22 21:46:08 +02:00
assert . Equal ( t , want , balancers . Servers ( ) [ 0 ] )
}
func TestBalancers_UpsertServer ( t * testing . T ) {
balancer1 , err := roundrobin . New ( nil )
require . NoError ( t , err )
balancer2 , err := roundrobin . New ( nil )
require . NoError ( t , err )
want , err := url . Parse ( "http://foo.com" )
require . NoError ( t , err )
balancers := Balancers ( [ ] Balancer { balancer1 , balancer2 } )
err = balancers . UpsertServer ( want )
require . NoError ( t , err )
2023-11-17 01:50:06 +01:00
assert . Len ( t , balancer1 . Servers ( ) , 1 )
2022-06-22 21:46:08 +02:00
assert . Equal ( t , want , balancer1 . Servers ( ) [ 0 ] )
2023-11-17 01:50:06 +01:00
assert . Len ( t , balancer2 . Servers ( ) , 1 )
2022-06-22 21:46:08 +02:00
assert . Equal ( t , want , balancer2 . Servers ( ) [ 0 ] )
}
func TestBalancers_RemoveServer ( t * testing . T ) {
server , err := url . Parse ( "http://foo.com" )
require . NoError ( t , err )
balancer1 , err := roundrobin . New ( nil )
require . NoError ( t , err )
err = balancer1 . UpsertServer ( server )
require . NoError ( t , err )
balancer2 , err := roundrobin . New ( nil )
require . NoError ( t , err )
err = balancer2 . UpsertServer ( server )
require . NoError ( t , err )
balancers := Balancers ( [ ] Balancer { balancer1 , balancer2 } )
err = balancers . RemoveServer ( server )
require . NoError ( t , err )
2023-11-17 01:50:06 +01:00
assert . Empty ( t , balancer1 . Servers ( ) )
assert . Empty ( t , balancer2 . Servers ( ) )
2022-06-22 21:46:08 +02:00
}
2017-06-03 15:02:28 +02:00
type testLoadBalancer struct {
// RWMutex needed due to parallel test execution: Both the system-under-test
// and the test assertions reference the counters.
* sync . RWMutex
numRemovedServers int
numUpsertedServers int
servers [ ] * url . URL
2019-05-16 10:58:06 +02:00
// options is just to make sure that LBStatusUpdater forwards options on Upsert to its BalancerHandler
options [ ] roundrobin . ServerOption
2017-06-03 15:02:28 +02:00
}
2017-05-10 14:28:57 -04:00
2018-06-11 11:36:03 +02:00
func ( lb * testLoadBalancer ) ServeHTTP ( w http . ResponseWriter , req * http . Request ) {
// noop
}
2017-06-03 15:02:28 +02:00
func ( lb * testLoadBalancer ) RemoveServer ( u * url . URL ) error {
lb . Lock ( )
defer lb . Unlock ( )
lb . numRemovedServers ++
lb . removeServer ( u )
return nil
2017-05-10 14:28:57 -04:00
}
2017-06-03 15:02:28 +02:00
func ( lb * testLoadBalancer ) UpsertServer ( u * url . URL , options ... roundrobin . ServerOption ) error {
lb . Lock ( )
defer lb . Unlock ( )
lb . numUpsertedServers ++
lb . servers = append ( lb . servers , u )
2019-05-16 10:58:06 +02:00
lb . options = append ( lb . options , options ... )
2017-06-03 15:02:28 +02:00
return nil
}
func ( lb * testLoadBalancer ) Servers ( ) [ ] * url . URL {
return lb . servers
}
2019-05-16 10:58:06 +02:00
func ( lb * testLoadBalancer ) Options ( ) [ ] roundrobin . ServerOption {
return lb . options
}
2017-06-03 15:02:28 +02:00
func ( lb * testLoadBalancer ) removeServer ( u * url . URL ) {
var i int
var serverURL * url . URL
2019-05-16 10:58:06 +02:00
found := false
2017-06-03 15:02:28 +02:00
for i , serverURL = range lb . servers {
if * serverURL == * u {
2019-05-16 10:58:06 +02:00
found = true
2017-06-03 15:02:28 +02:00
break
}
}
2019-05-16 10:58:06 +02:00
if ! found {
return
}
2017-06-03 15:02:28 +02:00
lb . servers = append ( lb . servers [ : i ] , lb . servers [ i + 1 : ] ... )
}
2018-05-22 09:22:03 +02:00
func newTestServer ( done func ( ) , healthSequence [ ] int ) * httptest . Server {
2017-06-03 15:02:28 +02:00
handler := & testHandler {
done : done ,
healthSequence : healthSequence ,
}
return httptest . NewServer ( handler )
}
2018-05-22 09:22:03 +02:00
// ServeHTTP returns HTTP response codes following a status sequences.
// It calls the given 'done' function once all request health indicators have been depleted.
2017-06-03 15:02:28 +02:00
func ( th * testHandler ) ServeHTTP ( w http . ResponseWriter , r * http . Request ) {
if len ( th . healthSequence ) == 0 {
panic ( "received unexpected request" )
}
2018-05-22 09:22:03 +02:00
w . WriteHeader ( th . healthSequence [ 0 ] )
2017-06-03 15:02:28 +02:00
th . healthSequence = th . healthSequence [ 1 : ]
if len ( th . healthSequence ) == 0 {
th . done ( )
2017-03-09 16:27:31 +01:00
}
}
2019-05-16 10:58:06 +02:00
func TestLBStatusUpdater ( t * testing . T ) {
lb := & testLoadBalancer { RWMutex : & sync . RWMutex { } }
2019-07-15 17:04:04 +02:00
svInfo := & runtime . ServiceInfo { }
2021-06-25 21:08:11 +02:00
lbsu := NewLBStatusUpdater ( lb , svInfo , nil )
2019-05-16 10:58:06 +02:00
newServer , err := url . Parse ( "http://foo.com" )
2020-07-19 07:10:03 -04:00
assert . NoError ( t , err )
2019-05-16 10:58:06 +02:00
err = lbsu . UpsertServer ( newServer , roundrobin . Weight ( 1 ) )
2020-07-19 07:10:03 -04:00
assert . NoError ( t , err )
2023-11-17 01:50:06 +01:00
assert . Len ( t , lbsu . Servers ( ) , 1 )
assert . Len ( t , lbsu . BalancerHandler . ( * testLoadBalancer ) . Options ( ) , 1 )
2019-05-16 10:58:06 +02:00
statuses := svInfo . GetAllStatus ( )
2023-11-17 01:50:06 +01:00
assert . Len ( t , statuses , 1 )
2019-05-16 10:58:06 +02:00
for k , v := range statuses {
2023-11-17 01:50:06 +01:00
assert . Equal ( t , newServer . String ( ) , k )
assert . Equal ( t , serverUp , v )
2019-05-16 10:58:06 +02:00
break
}
err = lbsu . RemoveServer ( newServer )
2020-07-19 07:10:03 -04:00
assert . NoError ( t , err )
2023-11-17 01:50:06 +01:00
assert . Empty ( t , lbsu . Servers ( ) )
2019-05-16 10:58:06 +02:00
statuses = svInfo . GetAllStatus ( )
2023-11-17 01:50:06 +01:00
assert . Len ( t , statuses , 1 )
2019-05-16 10:58:06 +02:00
for k , v := range statuses {
2023-11-17 01:50:06 +01:00
assert . Equal ( t , newServer . String ( ) , k )
assert . Equal ( t , serverDown , v )
2019-05-16 10:58:06 +02:00
break
}
}
2020-02-26 17:28:04 +01:00
func TestNotFollowingRedirects ( t * testing . T ) {
redirectServerCalled := false
redirectTestServer := httptest . NewServer ( http . HandlerFunc ( func ( rw http . ResponseWriter , req * http . Request ) {
redirectServerCalled = true
} ) )
defer redirectTestServer . Close ( )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
server := httptest . NewServer ( http . HandlerFunc ( func ( rw http . ResponseWriter , req * http . Request ) {
rw . Header ( ) . Add ( "location" , redirectTestServer . URL )
rw . WriteHeader ( http . StatusSeeOther )
cancel ( )
} ) )
defer server . Close ( )
lb := & testLoadBalancer {
RWMutex : & sync . RWMutex { } ,
servers : [ ] * url . URL { testhelpers . MustParseURL ( server . URL ) } ,
}
backend := NewBackendConfig ( Options {
Path : "/path" ,
Interval : healthCheckInterval ,
Timeout : healthCheckTimeout ,
LB : lb ,
FollowRedirects : false ,
} , "backendName" )
2020-09-26 13:30:03 +02:00
collectingMetrics := & testhelpers . CollectingGauge { }
2020-02-26 17:28:04 +01:00
check := HealthCheck {
Backends : make ( map [ string ] * BackendConfig ) ,
2020-09-26 13:30:03 +02:00
metrics : metricsHealthcheck { serverUpGauge : collectingMetrics } ,
2020-02-26 17:28:04 +01:00
}
wg := sync . WaitGroup { }
wg . Add ( 1 )
go func ( ) {
check . execute ( ctx , backend )
wg . Done ( )
} ( )
timeout := time . Duration ( int ( healthCheckInterval ) + 500 )
select {
case <- time . After ( timeout ) :
t . Fatal ( "test did not complete in time" )
case <- ctx . Done ( ) :
wg . Wait ( )
}
assert . False ( t , redirectServerCalled , "HTTP redirect must not be followed" )
}