1
0
Fork 0

Add support for readiness checks.

This commit is contained in:
Timo Reimann 2017-08-18 03:08:03 +02:00 committed by Traefiker
parent 3f76f73e8c
commit ea3510d1f3
8 changed files with 483 additions and 117 deletions

View file

@ -52,8 +52,8 @@ func TestMarathonLoadConfigNonAPIErrors(t *testing.T) {
}{
{
desc: "simple application",
application: createApplication(appPorts(80)),
task: createLocalhostTask(taskPorts(80)),
application: application(appPorts(80)),
task: localhostTask(taskPorts(80)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
@ -78,8 +78,8 @@ func TestMarathonLoadConfigNonAPIErrors(t *testing.T) {
},
{
desc: "filtered task",
application: createApplication(appPorts(80)),
task: createLocalhostTask(
application: application(appPorts(80)),
task: localhostTask(
taskPorts(80),
state(taskStateStaging),
),
@ -97,12 +97,12 @@ func TestMarathonLoadConfigNonAPIErrors(t *testing.T) {
},
{
desc: "load balancer / circuit breaker labels",
application: createApplication(
application: application(
appPorts(80),
label(types.LabelBackendLoadbalancerMethod, "drr"),
label(types.LabelBackendCircuitbreakerExpression, "NetworkErrorRatio() > 0.5"),
),
task: createLocalhostTask(taskPorts(80)),
task: localhostTask(taskPorts(80)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
@ -132,12 +132,12 @@ func TestMarathonLoadConfigNonAPIErrors(t *testing.T) {
},
{
desc: "general max connection labels",
application: createApplication(
application: application(
appPorts(80),
label(types.LabelBackendMaxconnAmount, "1000"),
label(types.LabelBackendMaxconnExtractorfunc, "client.ip"),
),
task: createLocalhostTask(taskPorts(80)),
task: localhostTask(taskPorts(80)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
@ -165,11 +165,11 @@ func TestMarathonLoadConfigNonAPIErrors(t *testing.T) {
},
{
desc: "max connection amount label only",
application: createApplication(
application: application(
appPorts(80),
label(types.LabelBackendMaxconnAmount, "1000"),
),
task: createLocalhostTask(taskPorts(80)),
task: localhostTask(taskPorts(80)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
@ -194,11 +194,11 @@ func TestMarathonLoadConfigNonAPIErrors(t *testing.T) {
},
{
desc: "max connection extractor function label only",
application: createApplication(
application: application(
appPorts(80),
label(types.LabelBackendMaxconnExtractorfunc, "client.ip"),
),
task: createLocalhostTask(taskPorts(80)),
task: localhostTask(taskPorts(80)),
expectedFrontends: map[string]*types.Frontend{
"frontend-app": {
Backend: "backend-app",
@ -223,12 +223,12 @@ func TestMarathonLoadConfigNonAPIErrors(t *testing.T) {
},
{
desc: "health check labels",
application: createApplication(
application: application(
appPorts(80),
label(types.LabelBackendHealthcheckPath, "/path"),
label(types.LabelBackendHealthcheckInterval, "5m"),
),
task: createTask(
task: task(
host("127.0.0.1"),
taskPorts(80),
),
@ -298,36 +298,37 @@ func TestMarathonLoadConfigNonAPIErrors(t *testing.T) {
func TestMarathonTaskFilter(t *testing.T) {
cases := []struct {
desc string
task marathon.Task
application marathon.Application
expected bool
desc string
task marathon.Task
application marathon.Application
readyChecker *readinessChecker
expected bool
}{
{
desc: "missing port",
task: createTask(),
application: createApplication(),
task: task(),
application: application(),
expected: false,
},
{
desc: "task not running",
task: createTask(
task: task(
taskPorts(80),
state(taskStateStaging),
),
application: createApplication(appPorts(80)),
application: application(appPorts(80)),
expected: false,
},
{
desc: "existing port",
task: createTask(taskPorts(80)),
application: createApplication(appPorts(80)),
task: task(taskPorts(80)),
application: application(appPorts(80)),
expected: true,
},
{
desc: "ambiguous port specification",
task: createTask(taskPorts(80, 443)),
application: createApplication(
task: task(taskPorts(80, 443)),
application: application(
appPorts(80, 443),
label(types.LabelPort, "443"),
label(types.LabelPortIndex, "1"),
@ -336,8 +337,8 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
desc: "healthcheck available",
task: createTask(taskPorts(80)),
application: createApplication(
task: task(taskPorts(80)),
application: application(
appPorts(80),
healthChecks(marathon.NewDefaultHealthCheck()),
),
@ -345,11 +346,11 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
desc: "healthcheck result false",
task: createTask(
task: task(
taskPorts(80),
healthCheckResultLiveness(false),
),
application: createApplication(
application: application(
appPorts(80),
healthChecks(marathon.NewDefaultHealthCheck()),
),
@ -357,11 +358,11 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
desc: "healthcheck results mixed",
task: createTask(
task: task(
taskPorts(80),
healthCheckResultLiveness(true, false),
),
application: createApplication(
application: application(
appPorts(80),
healthChecks(marathon.NewDefaultHealthCheck()),
),
@ -369,23 +370,35 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
desc: "healthcheck result true",
task: createTask(
task: task(
taskPorts(80),
healthCheckResultLiveness(true),
),
application: createApplication(
application: application(
appPorts(80),
healthChecks(marathon.NewDefaultHealthCheck()),
),
expected: true,
},
{
desc: "readiness check false",
task: task(taskPorts(80)),
application: application(
appPorts(80),
deployments("deploymentId"),
readinessCheck(0),
readinessCheckResult(testTaskName, false),
),
readyChecker: testReadinessChecker(),
expected: false,
},
}
for _, c := range cases {
c := c
t.Run(c.desc, func(t *testing.T) {
t.Parallel()
provider := &Provider{}
provider := &Provider{readyChecker: c.readyChecker}
actual := provider.taskFilter(c.task, c.application)
if actual != c.expected {
t.Errorf("actual %v, expected %v", actual, c.expected)
@ -403,19 +416,19 @@ func TestMarathonApplicationFilterConstraints(t *testing.T) {
}{
{
desc: "tags missing",
application: createApplication(),
application: application(),
marathonLBCompatibility: false,
expected: false,
},
{
desc: "tag matching",
application: createApplication(label(types.LabelTags, "valid")),
application: application(label(types.LabelTags, "valid")),
marathonLBCompatibility: false,
expected: true,
},
{
desc: "LB compatibility tag matching",
application: createApplication(
application: application(
label("HAPROXY_GROUP", "valid"),
label(types.LabelTags, "notvalid"),
),
@ -495,7 +508,7 @@ func TestMarathonApplicationFilterEnabled(t *testing.T) {
t.Run(c.desc, func(t *testing.T) {
t.Parallel()
provider := &Provider{ExposedByDefault: c.exposedByDefault}
app := createApplication(label(types.LabelEnable, c.enabledLabel))
app := application(label(types.LabelEnable, c.enabledLabel))
if provider.applicationFilter(app) != c.expected {
t.Errorf("got unexpected filtering = %t", !c.expected)
}
@ -514,70 +527,70 @@ func TestMarathonGetPort(t *testing.T) {
}{
{
desc: "port missing",
application: createApplication(),
task: createTask(),
application: application(),
task: task(),
expected: "",
},
{
desc: "numeric port",
application: createApplication(label(types.LabelPort, "80")),
task: createTask(),
application: application(label(types.LabelPort, "80")),
task: task(),
expected: "80",
},
{
desc: "string port",
application: createApplication(label(types.LabelPort, "foobar")),
task: createTask(taskPorts(80)),
application: application(label(types.LabelPort, "foobar")),
task: task(taskPorts(80)),
expected: "",
},
{
desc: "negative port",
application: createApplication(label(types.LabelPort, "-1")),
task: createTask(taskPorts(80)),
application: application(label(types.LabelPort, "-1")),
task: task(taskPorts(80)),
expected: "",
},
{
desc: "task port available",
application: createApplication(),
task: createTask(taskPorts(80)),
application: application(),
task: task(taskPorts(80)),
expected: "80",
},
{
desc: "port definition available",
application: createApplication(
application: application(
portDefinition(443),
),
task: createTask(),
task: task(),
expected: "443",
},
{
desc: "IP-per-task port available",
application: createApplication(ipAddrPerTask(8000)),
task: createTask(),
application: application(ipAddrPerTask(8000)),
task: task(),
expected: "8000",
},
{
desc: "multiple task ports available",
application: createApplication(),
task: createTask(taskPorts(80, 443)),
application: application(),
task: task(taskPorts(80, 443)),
expected: "80",
},
{
desc: "numeric port index specified",
application: createApplication(label(types.LabelPortIndex, "1")),
task: createTask(taskPorts(80, 443)),
application: application(label(types.LabelPortIndex, "1")),
task: task(taskPorts(80, 443)),
expected: "443",
},
{
desc: "string port index specified",
application: createApplication(label(types.LabelPortIndex, "foobar")),
task: createTask(taskPorts(80)),
application: application(label(types.LabelPortIndex, "foobar")),
task: task(taskPorts(80)),
expected: "",
},
{
desc: "task and application ports specified",
application: createApplication(appPorts(9999)),
task: createTask(taskPorts(7777)),
application: application(appPorts(9999)),
task: task(taskPorts(7777)),
expected: "7777",
},
}
@ -602,12 +615,12 @@ func TestMarathonGetWeight(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: "0",
},
{
desc: "label existing",
application: createApplication(label(types.LabelWeight, "10")),
application: application(label(types.LabelWeight, "10")),
expected: "10",
},
}
@ -633,12 +646,12 @@ func TestMarathonGetDomain(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: "docker.localhost",
},
{
desc: "label existing",
application: createApplication(label(types.LabelDomain, "foo.bar")),
application: application(label(types.LabelDomain, "foo.bar")),
expected: "foo.bar",
},
}
@ -666,12 +679,12 @@ func TestMarathonGetProtocol(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: "http",
},
{
desc: "label existing",
application: createApplication(label(types.LabelProtocol, "https")),
application: application(label(types.LabelProtocol, "https")),
expected: "https",
},
}
@ -697,12 +710,12 @@ func TestMarathonGetSticky(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: "false",
},
{
desc: "label existing",
application: createApplication(label(types.LabelBackendLoadbalancerSticky, "true")),
application: application(label(types.LabelBackendLoadbalancerSticky, "true")),
expected: "true",
},
}
@ -728,12 +741,12 @@ func TestMarathonGetPassHostHeader(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: "true",
},
{
desc: "label existing",
application: createApplication(label(types.LabelFrontendPassHostHeader, "false")),
application: application(label(types.LabelFrontendPassHostHeader, "false")),
expected: "false",
},
}
@ -759,17 +772,17 @@ func TestMarathonMaxConnAmount(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: math.MaxInt64,
},
{
desc: "non-integer value",
application: createApplication(label(types.LabelBackendMaxconnAmount, "foobar")),
application: application(label(types.LabelBackendMaxconnAmount, "foobar")),
expected: math.MaxInt64,
},
{
desc: "label existing",
application: createApplication(label(types.LabelBackendMaxconnAmount, "32")),
application: application(label(types.LabelBackendMaxconnAmount, "32")),
expected: 32,
},
}
@ -795,12 +808,12 @@ func TestMarathonGetMaxConnExtractorFunc(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: "request.host",
},
{
desc: "label existing",
application: createApplication(label(types.LabelBackendMaxconnExtractorfunc, "client.ip")),
application: application(label(types.LabelBackendMaxconnExtractorfunc, "client.ip")),
expected: "client.ip",
},
}
@ -826,12 +839,12 @@ func TestMarathonGetLoadBalancerMethod(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: "wrr",
},
{
desc: "label existing",
application: createApplication(label(types.LabelBackendLoadbalancerMethod, "drr")),
application: application(label(types.LabelBackendLoadbalancerMethod, "drr")),
expected: "drr",
},
}
@ -857,12 +870,12 @@ func TestMarathonGetCircuitBreakerExpression(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: "NetworkErrorRatio() > 1",
},
{
desc: "label existing",
application: createApplication(label(types.LabelBackendCircuitbreakerExpression, "NetworkErrorRatio() > 0.5")),
application: application(label(types.LabelBackendCircuitbreakerExpression, "NetworkErrorRatio() > 0.5")),
expected: "NetworkErrorRatio() > 0.5",
},
}
@ -888,12 +901,12 @@ func TestMarathonGetEntryPoints(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: []string{},
},
{
desc: "label existing",
application: createApplication(label(types.LabelFrontendEntryPoints, "http,https")),
application: application(label(types.LabelFrontendEntryPoints, "http,https")),
expected: []string{"http", "https"},
},
}
@ -920,13 +933,13 @@ func TestMarathonGetFrontendRule(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(appID("test")),
application: application(appID("test")),
marathonLBCompatibility: true,
expected: "Host:test.docker.localhost",
},
{
desc: "HAProxy vhost available and LB compat disabled",
application: createApplication(
application: application(
appID("test"),
label("HAPROXY_0_VHOST", "foo.bar"),
),
@ -935,14 +948,14 @@ func TestMarathonGetFrontendRule(t *testing.T) {
},
{
desc: "HAProxy vhost available and LB compat enabled",
application: createApplication(label("HAPROXY_0_VHOST", "foo.bar")),
application: application(label("HAPROXY_0_VHOST", "foo.bar")),
marathonLBCompatibility: true,
expected: "Host:foo.bar",
},
{
desc: "frontend rule available",
application: createApplication(
application: application(
label(types.LabelFrontendRule, "Host:foo.bar"),
label("HAPROXY_0_VHOST", "unused"),
),
@ -975,12 +988,12 @@ func TestMarathonGetBackend(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(appID("/group/app")),
application: application(appID("/group/app")),
expected: "-group-app",
},
{
desc: "label existing",
application: createApplication(label(types.LabelBackend, "bar")),
application: application(label(types.LabelBackend, "bar")),
expected: "bar",
},
}
@ -1056,7 +1069,7 @@ func TestMarathonHasHealthCheckLabels(t *testing.T) {
c := c
t.Run(c.desc, func(t *testing.T) {
t.Parallel()
app := createApplication()
app := application()
if c.value != nil {
app.AddLabel(types.LabelBackendHealthcheckPath, *c.value)
}
@ -1090,7 +1103,7 @@ func TestMarathonGetHealthCheckPath(t *testing.T) {
c := c
t.Run(c.desc, func(t *testing.T) {
t.Parallel()
app := createApplication()
app := application()
if c.value != "" {
app.AddLabel(types.LabelBackendHealthcheckPath, c.value)
}
@ -1124,7 +1137,7 @@ func TestMarathonGetHealthCheckInterval(t *testing.T) {
c := c
t.Run(c.desc, func(t *testing.T) {
t.Parallel()
app := createApplication()
app := application()
if c.value != "" {
app.AddLabel(types.LabelBackendHealthcheckInterval, c.value)
}
@ -1148,49 +1161,49 @@ func TestGetBackendServer(t *testing.T) {
}{
{
desc: "application without IP-per-task",
application: createApplication(),
application: application(),
expectedServer: host,
},
{
desc: "task hostname override",
application: createApplication(ipAddrPerTask(8000)),
application: application(ipAddrPerTask(8000)),
forceTaskHostname: true,
expectedServer: host,
},
{
desc: "task IP address missing",
application: createApplication(ipAddrPerTask(8000)),
task: createTask(),
application: application(ipAddrPerTask(8000)),
task: task(),
expectedServer: "",
},
{
desc: "single task IP address",
application: createApplication(ipAddrPerTask(8000)),
task: createTask(ipAddresses("1.1.1.1")),
application: application(ipAddrPerTask(8000)),
task: task(ipAddresses("1.1.1.1")),
expectedServer: "1.1.1.1",
},
{
desc: "multiple task IP addresses without index label",
application: createApplication(ipAddrPerTask(8000)),
task: createTask(ipAddresses("1.1.1.1", "2.2.2.2")),
application: application(ipAddrPerTask(8000)),
task: task(ipAddresses("1.1.1.1", "2.2.2.2")),
expectedServer: "",
},
{
desc: "multiple task IP addresses with invalid index label",
application: createApplication(
application: application(
label("traefik.ipAddressIdx", "invalid"),
ipAddrPerTask(8000),
),
task: createTask(ipAddresses("1.1.1.1", "2.2.2.2")),
task: task(ipAddresses("1.1.1.1", "2.2.2.2")),
expectedServer: "",
},
{
desc: "multiple task IP addresses with valid index label",
application: createApplication(
application: application(
label("traefik.ipAddressIdx", "1"),
ipAddrPerTask(8000),
),
task: createTask(ipAddresses("1.1.1.1", "2.2.2.2")),
task: task(ipAddresses("1.1.1.1", "2.2.2.2")),
expectedServer: "2.2.2.2",
},
}
@ -1275,12 +1288,12 @@ func TestMarathonGetBasicAuth(t *testing.T) {
}{
{
desc: "label missing",
application: createApplication(),
application: application(),
expected: []string{},
},
{
desc: "label existing",
application: createApplication(label(types.LabelFrontendAuthBasic, "user:password")),
application: application(label(types.LabelFrontendAuthBasic, "user:password")),
expected: []string{"user:password"},
},
}