2017-03-15 18:16:06 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/url"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2017-03-24 08:36:33 +00:00
|
|
|
"github.com/containous/flaeg"
|
2017-03-15 18:16:06 +00:00
|
|
|
"github.com/containous/traefik/healthcheck"
|
|
|
|
"github.com/containous/traefik/types"
|
|
|
|
"github.com/vulcand/oxy/roundrobin"
|
|
|
|
)
|
|
|
|
|
|
|
|
type testLoadBalancer struct{}
|
|
|
|
|
|
|
|
func (lb *testLoadBalancer) RemoveServer(u *url.URL) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (lb *testLoadBalancer) UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (lb *testLoadBalancer) Servers() []*url.URL {
|
|
|
|
return []*url.URL{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestServerLoadConfigHealthCheckOptions(t *testing.T) {
|
|
|
|
healthChecks := []*types.HealthCheck{
|
|
|
|
nil,
|
|
|
|
{
|
|
|
|
Path: "/path",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, lbMethod := range []string{"Wrr", "Drr"} {
|
|
|
|
for _, healthCheck := range healthChecks {
|
|
|
|
t.Run(fmt.Sprintf("%s/hc=%t", lbMethod, healthCheck != nil), func(t *testing.T) {
|
|
|
|
globalConfig := GlobalConfiguration{
|
|
|
|
EntryPoints: EntryPoints{
|
|
|
|
"http": &EntryPoint{},
|
|
|
|
},
|
2017-03-24 08:36:33 +00:00
|
|
|
HealthCheck: &HealthCheckConfig{Interval: flaeg.Duration(5 * time.Second)},
|
2017-03-15 18:16:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
dynamicConfigs := configs{
|
|
|
|
"config": &types.Configuration{
|
|
|
|
Frontends: map[string]*types.Frontend{
|
|
|
|
"frontend": {
|
|
|
|
EntryPoints: []string{"http"},
|
|
|
|
Backend: "backend",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Backends: map[string]*types.Backend{
|
|
|
|
"backend": {
|
|
|
|
Servers: map[string]types.Server{
|
|
|
|
"server": {
|
|
|
|
URL: "http://localhost",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
LoadBalancer: &types.LoadBalancer{
|
|
|
|
Method: lbMethod,
|
|
|
|
},
|
|
|
|
HealthCheck: healthCheck,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
srv := NewServer(globalConfig)
|
|
|
|
if _, err := srv.loadConfig(dynamicConfigs, globalConfig); err != nil {
|
|
|
|
t.Fatalf("got error: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
wantNumHealthCheckBackends := 0
|
|
|
|
if healthCheck != nil {
|
|
|
|
wantNumHealthCheckBackends = 1
|
|
|
|
}
|
|
|
|
gotNumHealthCheckBackends := len(healthcheck.GetHealthCheck().Backends)
|
|
|
|
if gotNumHealthCheckBackends != wantNumHealthCheckBackends {
|
|
|
|
t.Errorf("got %d health check backends, want %d", gotNumHealthCheckBackends, wantNumHealthCheckBackends)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestServerParseHealthCheckOptions(t *testing.T) {
|
|
|
|
lb := &testLoadBalancer{}
|
2017-03-24 08:36:33 +00:00
|
|
|
globalInterval := 15 * time.Second
|
2017-03-15 18:16:06 +00:00
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
desc string
|
|
|
|
hc *types.HealthCheck
|
|
|
|
wantOpts *healthcheck.Options
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "nil health check",
|
|
|
|
hc: nil,
|
|
|
|
wantOpts: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "empty path",
|
|
|
|
hc: &types.HealthCheck{
|
|
|
|
Path: "",
|
|
|
|
},
|
|
|
|
wantOpts: nil,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "unparseable interval",
|
|
|
|
hc: &types.HealthCheck{
|
|
|
|
Path: "/path",
|
|
|
|
Interval: "unparseable",
|
|
|
|
},
|
|
|
|
wantOpts: &healthcheck.Options{
|
|
|
|
Path: "/path",
|
2017-03-24 08:36:33 +00:00
|
|
|
Interval: globalInterval,
|
2017-03-15 18:16:06 +00:00
|
|
|
LB: lb,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "sub-zero interval",
|
|
|
|
hc: &types.HealthCheck{
|
|
|
|
Path: "/path",
|
2017-03-24 08:36:33 +00:00
|
|
|
Interval: "-42s",
|
2017-03-15 18:16:06 +00:00
|
|
|
},
|
|
|
|
wantOpts: &healthcheck.Options{
|
|
|
|
Path: "/path",
|
2017-03-24 08:36:33 +00:00
|
|
|
Interval: globalInterval,
|
2017-03-15 18:16:06 +00:00
|
|
|
LB: lb,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "parseable interval",
|
|
|
|
hc: &types.HealthCheck{
|
|
|
|
Path: "/path",
|
|
|
|
Interval: "5m",
|
|
|
|
},
|
|
|
|
wantOpts: &healthcheck.Options{
|
|
|
|
Path: "/path",
|
|
|
|
Interval: 5 * time.Minute,
|
|
|
|
LB: lb,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
|
|
|
test := test
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2017-05-15 07:02:32 +00:00
|
|
|
gotOpts := parseHealthCheckOptions(lb, "backend", test.hc, &HealthCheckConfig{Interval: flaeg.Duration(globalInterval)})
|
2017-03-15 18:16:06 +00:00
|
|
|
if !reflect.DeepEqual(gotOpts, test.wantOpts) {
|
|
|
|
t.Errorf("got health check options %+v, want %+v", gotOpts, test.wantOpts)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2017-05-15 07:02:32 +00:00
|
|
|
|
|
|
|
func TestServerLoadConfigEmptyBasicAuth(t *testing.T) {
|
|
|
|
globalConfig := GlobalConfiguration{
|
|
|
|
EntryPoints: EntryPoints{
|
|
|
|
"http": &EntryPoint{},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
dynamicConfigs := configs{
|
|
|
|
"config": &types.Configuration{
|
|
|
|
Frontends: map[string]*types.Frontend{
|
|
|
|
"frontend": {
|
|
|
|
EntryPoints: []string{"http"},
|
|
|
|
Backend: "backend",
|
|
|
|
BasicAuth: []string{""},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Backends: map[string]*types.Backend{
|
|
|
|
"backend": {
|
|
|
|
Servers: map[string]types.Server{
|
|
|
|
"server": {
|
|
|
|
URL: "http://localhost",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
LoadBalancer: &types.LoadBalancer{
|
|
|
|
Method: "Wrr",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
srv := NewServer(globalConfig)
|
|
|
|
if _, err := srv.loadConfig(dynamicConfigs, globalConfig); err != nil {
|
|
|
|
t.Fatalf("got error: %s", err)
|
|
|
|
}
|
|
|
|
}
|