2015-11-13 11:50:32 +01:00
package provider
import (
2016-12-30 09:21:13 +01:00
"errors"
2015-11-13 11:50:32 +01:00
"reflect"
"testing"
2016-02-24 16:43:39 +01:00
"github.com/containous/traefik/mocks"
"github.com/containous/traefik/types"
2015-11-13 11:50:32 +01:00
"github.com/gambol99/go-marathon"
2016-02-09 23:10:24 +01:00
"github.com/stretchr/testify/mock"
2015-11-13 11:50:32 +01:00
)
type fakeClient struct {
2016-02-09 23:10:24 +01:00
mocks . Marathon
2015-11-13 11:50:32 +01:00
}
2016-02-09 23:10:24 +01:00
func newFakeClient ( applicationsError bool , applications * marathon . Applications , tasksError bool , tasks * marathon . Tasks ) * fakeClient {
// create an instance of our test object
fakeClient := new ( fakeClient )
if applicationsError {
2016-06-20 17:11:07 +02:00
fakeClient . On ( "Applications" , mock . Anything ) . Return ( nil , errors . New ( "error" ) )
} else {
fakeClient . On ( "Applications" , mock . Anything ) . Return ( applications , nil )
2015-11-13 11:50:32 +01:00
}
2016-06-20 17:11:07 +02:00
if ! applicationsError {
if tasksError {
fakeClient . On ( "AllTasks" , mock . Anything ) . Return ( nil , errors . New ( "error" ) )
} else {
fakeClient . On ( "AllTasks" , mock . Anything ) . Return ( tasks , nil )
}
2015-11-13 11:50:32 +01:00
}
2016-02-09 23:10:24 +01:00
return fakeClient
2015-11-13 11:50:32 +01:00
}
func TestMarathonLoadConfig ( t * testing . T ) {
cases := [ ] struct {
applicationsError bool
applications * marathon . Applications
tasksError bool
tasks * marathon . Tasks
expectedNil bool
expectedFrontends map [ string ] * types . Frontend
expectedBackends map [ string ] * types . Backend
} {
{
applications : & marathon . Applications { } ,
tasks : & marathon . Tasks { } ,
expectedFrontends : map [ string ] * types . Frontend { } ,
expectedBackends : map [ string ] * types . Backend { } ,
} ,
{
applicationsError : true ,
applications : & marathon . Applications { } ,
tasks : & marathon . Tasks { } ,
expectedNil : true ,
expectedFrontends : map [ string ] * types . Frontend { } ,
expectedBackends : map [ string ] * types . Backend { } ,
} ,
{
applications : & marathon . Applications { } ,
tasksError : true ,
tasks : & marathon . Tasks { } ,
expectedNil : true ,
expectedFrontends : map [ string ] * types . Frontend { } ,
expectedBackends : map [ string ] * types . Backend { } ,
} ,
{
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-06-20 17:11:07 +02:00
ID : "/test" ,
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string { } ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
tasks : & marathon . Tasks {
Tasks : [ ] marathon . Task {
{
ID : "test" ,
AppID : "/test" ,
2017-01-06 13:26:50 -02:00
Host : "localhost" ,
2015-11-13 11:50:32 +01:00
Ports : [ ] int { 80 } ,
2017-01-06 13:26:50 -02:00
IPAddresses : [ ] * marathon . IPAddress {
{
IPAddress : "127.0.0.1" ,
Protocol : "tcp" ,
} ,
} ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
expectedFrontends : map [ string ] * types . Frontend {
` frontend-test ` : {
2016-05-10 07:43:24 -04:00
Backend : "backend-test" ,
PassHostHeader : true ,
EntryPoints : [ ] string { } ,
2015-11-13 11:50:32 +01:00
Routes : map [ string ] types . Route {
` route-host-test ` : {
2016-03-27 01:05:17 +01:00
Rule : "Host:test.docker.localhost" ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
} ,
expectedBackends : map [ string ] * types . Backend {
"backend-test" : {
Servers : map [ string ] types . Server {
"server-test" : {
URL : "http://127.0.0.1:80" ,
Weight : 0 ,
} ,
} ,
CircuitBreaker : nil ,
} ,
} ,
} ,
2016-08-13 12:55:15 -04:00
{
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-10-11 16:12:23 +02:00
ID : "/testLoadBalancerAndCircuitBreaker.dot" ,
2016-08-13 12:55:15 -04:00
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string {
"traefik.backend.loadbalancer.method" : "drr" ,
"traefik.backend.circuitbreaker.expression" : "NetworkErrorRatio() > 0.5" ,
} ,
} ,
} ,
} ,
tasks : & marathon . Tasks {
Tasks : [ ] marathon . Task {
{
2016-10-11 16:12:23 +02:00
ID : "testLoadBalancerAndCircuitBreaker.dot" ,
AppID : "/testLoadBalancerAndCircuitBreaker.dot" ,
2017-01-06 13:26:50 -02:00
Host : "localhost" ,
2016-08-13 12:55:15 -04:00
Ports : [ ] int { 80 } ,
2017-01-06 13:26:50 -02:00
IPAddresses : [ ] * marathon . IPAddress {
{
IPAddress : "127.0.0.1" ,
Protocol : "tcp" ,
} ,
} ,
2016-08-13 12:55:15 -04:00
} ,
} ,
} ,
expectedFrontends : map [ string ] * types . Frontend {
2016-10-11 16:12:23 +02:00
` frontend-testLoadBalancerAndCircuitBreaker.dot ` : {
Backend : "backend-testLoadBalancerAndCircuitBreaker.dot" ,
2016-08-13 12:55:15 -04:00
PassHostHeader : true ,
EntryPoints : [ ] string { } ,
Routes : map [ string ] types . Route {
2016-10-11 16:12:23 +02:00
` route-host-testLoadBalancerAndCircuitBreaker.dot ` : {
Rule : "Host:testLoadBalancerAndCircuitBreaker.dot.docker.localhost" ,
2016-08-13 12:55:15 -04:00
} ,
} ,
} ,
} ,
expectedBackends : map [ string ] * types . Backend {
2016-10-11 16:12:23 +02:00
"backend-testLoadBalancerAndCircuitBreaker.dot" : {
2016-08-13 12:55:15 -04:00
Servers : map [ string ] types . Server {
2016-10-11 16:12:23 +02:00
"server-testLoadBalancerAndCircuitBreaker-dot" : {
2016-08-13 12:55:15 -04:00
URL : "http://127.0.0.1:80" ,
Weight : 0 ,
} ,
} ,
CircuitBreaker : & types . CircuitBreaker {
Expression : "NetworkErrorRatio() > 0.5" ,
} ,
LoadBalancer : & types . LoadBalancer {
Method : "drr" ,
} ,
} ,
} ,
} ,
{
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "/testMaxConn" ,
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string {
"traefik.backend.maxconn.amount" : "1000" ,
"traefik.backend.maxconn.extractorfunc" : "client.ip" ,
} ,
} ,
} ,
} ,
tasks : & marathon . Tasks {
Tasks : [ ] marathon . Task {
{
ID : "testMaxConn" ,
AppID : "/testMaxConn" ,
2017-01-06 13:26:50 -02:00
Host : "localhost" ,
2016-08-13 12:55:15 -04:00
Ports : [ ] int { 80 } ,
2017-01-06 13:26:50 -02:00
IPAddresses : [ ] * marathon . IPAddress {
{
IPAddress : "127.0.0.1" ,
Protocol : "tcp" ,
} ,
} ,
2016-08-13 12:55:15 -04:00
} ,
} ,
} ,
expectedFrontends : map [ string ] * types . Frontend {
` frontend-testMaxConn ` : {
Backend : "backend-testMaxConn" ,
PassHostHeader : true ,
EntryPoints : [ ] string { } ,
Routes : map [ string ] types . Route {
` route-host-testMaxConn ` : {
Rule : "Host:testMaxConn.docker.localhost" ,
} ,
} ,
} ,
} ,
expectedBackends : map [ string ] * types . Backend {
"backend-testMaxConn" : {
Servers : map [ string ] types . Server {
"server-testMaxConn" : {
URL : "http://127.0.0.1:80" ,
Weight : 0 ,
} ,
} ,
MaxConn : & types . MaxConn {
Amount : 1000 ,
ExtractorFunc : "client.ip" ,
} ,
} ,
} ,
} ,
{
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "/testMaxConnOnlySpecifyAmount" ,
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string {
"traefik.backend.maxconn.amount" : "1000" ,
} ,
} ,
} ,
} ,
tasks : & marathon . Tasks {
Tasks : [ ] marathon . Task {
{
ID : "testMaxConnOnlySpecifyAmount" ,
AppID : "/testMaxConnOnlySpecifyAmount" ,
2017-01-06 13:26:50 -02:00
Host : "localhost" ,
2016-08-13 12:55:15 -04:00
Ports : [ ] int { 80 } ,
2017-01-06 13:26:50 -02:00
IPAddresses : [ ] * marathon . IPAddress {
{
IPAddress : "127.0.0.1" ,
Protocol : "tcp" ,
} ,
} ,
2016-08-13 12:55:15 -04:00
} ,
} ,
} ,
expectedFrontends : map [ string ] * types . Frontend {
` frontend-testMaxConnOnlySpecifyAmount ` : {
Backend : "backend-testMaxConnOnlySpecifyAmount" ,
PassHostHeader : true ,
EntryPoints : [ ] string { } ,
Routes : map [ string ] types . Route {
` route-host-testMaxConnOnlySpecifyAmount ` : {
Rule : "Host:testMaxConnOnlySpecifyAmount.docker.localhost" ,
} ,
} ,
} ,
} ,
expectedBackends : map [ string ] * types . Backend {
"backend-testMaxConnOnlySpecifyAmount" : {
Servers : map [ string ] types . Server {
"server-testMaxConnOnlySpecifyAmount" : {
URL : "http://127.0.0.1:80" ,
Weight : 0 ,
} ,
} ,
MaxConn : nil ,
} ,
} ,
} ,
{
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "/testMaxConnOnlyExtractorFunc" ,
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string {
"traefik.backend.maxconn.extractorfunc" : "client.ip" ,
} ,
} ,
} ,
} ,
tasks : & marathon . Tasks {
Tasks : [ ] marathon . Task {
{
ID : "testMaxConnOnlyExtractorFunc" ,
AppID : "/testMaxConnOnlyExtractorFunc" ,
2017-01-06 13:26:50 -02:00
Host : "localhost" ,
2016-08-13 12:55:15 -04:00
Ports : [ ] int { 80 } ,
2017-01-06 13:26:50 -02:00
IPAddresses : [ ] * marathon . IPAddress {
{
IPAddress : "127.0.0.1" ,
Protocol : "tcp" ,
} ,
} ,
2016-08-13 12:55:15 -04:00
} ,
} ,
} ,
expectedFrontends : map [ string ] * types . Frontend {
` frontend-testMaxConnOnlyExtractorFunc ` : {
Backend : "backend-testMaxConnOnlyExtractorFunc" ,
PassHostHeader : true ,
EntryPoints : [ ] string { } ,
Routes : map [ string ] types . Route {
` route-host-testMaxConnOnlyExtractorFunc ` : {
Rule : "Host:testMaxConnOnlyExtractorFunc.docker.localhost" ,
} ,
} ,
} ,
} ,
expectedBackends : map [ string ] * types . Backend {
"backend-testMaxConnOnlyExtractorFunc" : {
Servers : map [ string ] types . Server {
"server-testMaxConnOnlyExtractorFunc" : {
URL : "http://127.0.0.1:80" ,
Weight : 0 ,
} ,
} ,
MaxConn : nil ,
} ,
} ,
} ,
2015-11-13 11:50:32 +01:00
}
for _ , c := range cases {
2016-02-09 23:10:24 +01:00
fakeClient := newFakeClient ( c . applicationsError , c . applications , c . tasksError , c . tasks )
2015-11-13 11:50:32 +01:00
provider := & Marathon {
2016-03-21 12:37:02 +03:00
Domain : "docker.localhost" ,
ExposedByDefault : true ,
marathonClient : fakeClient ,
2015-11-13 11:50:32 +01:00
}
actualConfig := provider . loadMarathonConfig ( )
2016-06-20 17:11:07 +02:00
fakeClient . AssertExpectations ( t )
2015-11-13 11:50:32 +01:00
if c . expectedNil {
if actualConfig != nil {
t . Fatalf ( "Should have been nil, got %v" , actualConfig )
}
} else {
// Compare backends
if ! reflect . DeepEqual ( actualConfig . Backends , c . expectedBackends ) {
t . Fatalf ( "expected %#v, got %#v" , c . expectedBackends , actualConfig . Backends )
}
if ! reflect . DeepEqual ( actualConfig . Frontends , c . expectedFrontends ) {
t . Fatalf ( "expected %#v, got %#v" , c . expectedFrontends , actualConfig . Frontends )
}
}
}
}
func TestMarathonTaskFilter ( t * testing . T ) {
cases := [ ] struct {
2016-03-21 12:37:02 +03:00
task marathon . Task
applications * marathon . Applications
expected bool
exposedByDefault bool
2015-11-13 11:50:32 +01:00
} {
{
2016-03-21 12:37:02 +03:00
task : marathon . Task { } ,
applications : & marathon . Applications { } ,
expected : false ,
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
{
task : marathon . Task {
AppID : "test" ,
Ports : [ ] int { 80 } ,
} ,
2016-03-21 12:37:02 +03:00
applications : & marathon . Applications { } ,
expected : false ,
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
{
task : marathon . Task {
AppID : "test" ,
Ports : [ ] int { 80 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-06-20 17:11:07 +02:00
ID : "foo" ,
Labels : & map [ string ] string { } ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : false ,
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
{
task : marathon . Task {
2016-10-27 15:49:07 +02:00
AppID : "multiple-ports" ,
2016-10-27 15:49:34 +02:00
Ports : [ ] int { 80 , 443 } ,
2015-11-13 11:50:32 +01:00
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-10-27 15:49:07 +02:00
ID : "multiple-ports" ,
2016-06-20 17:11:07 +02:00
Ports : [ ] int { 80 , 443 } ,
Labels : & map [ string ] string { } ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
2016-10-27 15:49:34 +02:00
expected : true ,
2016-03-21 12:37:02 +03:00
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
{
task : marathon . Task {
2017-01-06 13:26:50 -02:00
AppID : "ipAddressOnePort" ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "ipAddressOnePort" ,
IPAddressPerTask : & marathon . IPAddressPerTask {
Discovery : & marathon . Discovery {
Ports : & [ ] marathon . Port {
{
Number : 8880 ,
Name : "p1" ,
} ,
} ,
} ,
} ,
Labels : & map [ string ] string { } ,
} ,
} ,
} ,
expected : true ,
exposedByDefault : true ,
} ,
{
task : marathon . Task {
AppID : "ipAddressTwoPortsUseFirst" ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "ipAddressTwoPortsUseFirst" ,
IPAddressPerTask : & marathon . IPAddressPerTask {
Discovery : & marathon . Discovery {
Ports : & [ ] marathon . Port {
{
Number : 8898 ,
Name : "p1" ,
} , {
Number : 9999 ,
Name : "p1" ,
} ,
} ,
} ,
} ,
Labels : & map [ string ] string { } ,
} ,
} ,
} ,
expected : true ,
exposedByDefault : true ,
} ,
{
task : marathon . Task {
AppID : "ipAddressValidTwoPorts" ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "ipAddressValidTwoPorts" ,
IPAddressPerTask : & marathon . IPAddressPerTask {
Discovery : & marathon . Discovery {
Ports : & [ ] marathon . Port {
{
Number : 8898 ,
Name : "p1" ,
} , {
Number : 9999 ,
Name : "p2" ,
} ,
} ,
} ,
} ,
Labels : & map [ string ] string {
"traefik.portIndex" : "0" ,
} ,
} ,
} ,
} ,
expected : true ,
exposedByDefault : true ,
} ,
{
task : marathon . Task {
2015-11-13 11:50:32 +01:00
Ports : [ ] int { 80 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-10-27 15:49:07 +02:00
ID : "disable" ,
2015-11-13 11:50:32 +01:00
Ports : [ ] int { 80 } ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-11-13 11:50:32 +01:00
"traefik.enable" : "false" ,
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : false ,
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
2015-12-05 10:59:01 -08:00
{
task : marathon . Task {
AppID : "specify-port-number" ,
Ports : [ ] int { 80 , 443 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "specify-port-number" ,
Ports : [ ] int { 80 , 443 } ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-12-05 10:59:01 -08:00
"traefik.port" : "80" ,
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : true ,
exposedByDefault : true ,
2015-12-05 10:59:01 -08:00
} ,
{
task : marathon . Task {
AppID : "specify-unknown-port-number" ,
Ports : [ ] int { 80 , 443 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "specify-unknown-port-number" ,
Ports : [ ] int { 80 , 443 } ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-12-05 10:59:01 -08:00
"traefik.port" : "8080" ,
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : false ,
exposedByDefault : true ,
2015-12-05 10:59:01 -08:00
} ,
{
task : marathon . Task {
AppID : "specify-port-index" ,
Ports : [ ] int { 80 , 443 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "specify-port-index" ,
Ports : [ ] int { 80 , 443 } ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-12-05 10:59:01 -08:00
"traefik.portIndex" : "0" ,
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : true ,
exposedByDefault : true ,
2015-12-05 10:59:01 -08:00
} ,
{
task : marathon . Task {
AppID : "specify-out-of-range-port-index" ,
Ports : [ ] int { 80 , 443 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "specify-out-of-range-port-index" ,
Ports : [ ] int { 80 , 443 } ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-12-05 10:59:01 -08:00
"traefik.portIndex" : "2" ,
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : false ,
exposedByDefault : true ,
2015-12-05 10:59:01 -08:00
} ,
{
task : marathon . Task {
AppID : "specify-both-port-index-and-number" ,
Ports : [ ] int { 80 , 443 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "specify-both-port-index-and-number" ,
Ports : [ ] int { 80 , 443 } ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-12-05 10:59:01 -08:00
"traefik.port" : "443" ,
"traefik.portIndex" : "1" ,
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : false ,
exposedByDefault : true ,
2015-12-05 10:59:01 -08:00
} ,
2015-11-13 11:50:32 +01:00
{
task : marathon . Task {
AppID : "foo" ,
Ports : [ ] int { 80 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-06-20 17:11:07 +02:00
ID : "foo" ,
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string { } ,
HealthChecks : & [ ] marathon . HealthCheck {
* marathon . NewDefaultHealthCheck ( ) ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
} ,
2017-01-28 08:01:37 -05:00
expected : false ,
2016-03-21 12:37:02 +03:00
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
{
task : marathon . Task {
2016-10-27 15:49:07 +02:00
AppID : "healthcheck-false" ,
2015-11-13 11:50:32 +01:00
Ports : [ ] int { 80 } ,
2016-02-09 23:10:24 +01:00
HealthCheckResults : [ ] * marathon . HealthCheckResult {
2015-11-13 11:50:32 +01:00
{
Alive : false ,
} ,
} ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-10-27 15:49:07 +02:00
ID : "healthcheck-false" ,
2016-06-20 17:11:07 +02:00
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string { } ,
HealthChecks : & [ ] marathon . HealthCheck {
* marathon . NewDefaultHealthCheck ( ) ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : false ,
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
{
task : marathon . Task {
AppID : "foo" ,
Ports : [ ] int { 80 } ,
2016-02-09 23:10:24 +01:00
HealthCheckResults : [ ] * marathon . HealthCheckResult {
2015-11-13 11:50:32 +01:00
{
Alive : true ,
} ,
{
Alive : false ,
} ,
} ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-06-20 17:11:07 +02:00
ID : "foo" ,
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string { } ,
HealthChecks : & [ ] marathon . HealthCheck {
* marathon . NewDefaultHealthCheck ( ) ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : false ,
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
{
task : marathon . Task {
2016-10-27 15:49:07 +02:00
AppID : "single-port" ,
2015-11-13 11:50:32 +01:00
Ports : [ ] int { 80 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-10-27 15:49:07 +02:00
ID : "single-port" ,
2016-06-20 17:11:07 +02:00
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string { } ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : true ,
exposedByDefault : true ,
2015-11-13 11:50:32 +01:00
} ,
{
task : marathon . Task {
2016-10-27 15:49:07 +02:00
AppID : "healthcheck-alive" ,
2015-11-13 11:50:32 +01:00
Ports : [ ] int { 80 } ,
2016-02-09 23:10:24 +01:00
HealthCheckResults : [ ] * marathon . HealthCheckResult {
2015-11-13 11:50:32 +01:00
{
Alive : true ,
} ,
} ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-10-27 15:49:07 +02:00
ID : "healthcheck-alive" ,
2016-06-20 17:11:07 +02:00
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string { } ,
HealthChecks : & [ ] marathon . HealthCheck {
* marathon . NewDefaultHealthCheck ( ) ,
2015-11-13 11:50:32 +01:00
} ,
} ,
} ,
} ,
2016-03-21 12:37:02 +03:00
expected : true ,
exposedByDefault : true ,
} ,
{
task : marathon . Task {
AppID : "disable-default-expose" ,
Ports : [ ] int { 80 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
2016-06-20 17:11:07 +02:00
ID : "disable-default-expose" ,
Ports : [ ] int { 80 } ,
Labels : & map [ string ] string { } ,
2016-03-21 12:37:02 +03:00
} ,
} ,
} ,
expected : false ,
exposedByDefault : false ,
} ,
{
task : marathon . Task {
AppID : "disable-default-expose-disable-in-label" ,
Ports : [ ] int { 80 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "disable-default-expose-disable-in-label" ,
Ports : [ ] int { 80 } ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2016-03-21 12:37:02 +03:00
"traefik.enable" : "false" ,
} ,
} ,
} ,
} ,
expected : false ,
exposedByDefault : false ,
} ,
{
task : marathon . Task {
AppID : "disable-default-expose-enable-in-label" ,
Ports : [ ] int { 80 } ,
} ,
applications : & marathon . Applications {
Apps : [ ] marathon . Application {
{
ID : "disable-default-expose-enable-in-label" ,
Ports : [ ] int { 80 } ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2016-03-21 12:37:02 +03:00
"traefik.enable" : "true" ,
} ,
} ,
} ,
} ,
expected : true ,
exposedByDefault : false ,
2015-11-13 11:50:32 +01:00
} ,
}
2016-09-20 09:44:32 +01:00
provider := & Marathon { }
2015-11-13 11:50:32 +01:00
for _ , c := range cases {
2016-09-20 09:44:32 +01:00
actual := provider . taskFilter ( c . task , c . applications , c . exposedByDefault )
2015-11-13 11:50:32 +01:00
if actual != c . expected {
2016-10-27 15:49:07 +02:00
t . Fatalf ( "App %s: expected %v, got %v" , c . task . AppID , c . expected , actual )
2015-11-13 11:50:32 +01:00
}
}
}
2016-09-21 00:15:09 +01:00
func TestMarathonAppConstraints ( t * testing . T ) {
cases := [ ] struct {
2016-10-06 17:42:19 +02:00
application marathon . Application
filteredTasks [ ] marathon . Task
expected bool
marathonLBCompatibility bool
2016-09-21 00:15:09 +01:00
} {
{
application : marathon . Application {
ID : "foo1" ,
Labels : & map [ string ] string { } ,
} ,
filteredTasks : [ ] marathon . Task {
{
AppID : "foo1" ,
} ,
} ,
2016-10-06 17:42:19 +02:00
marathonLBCompatibility : false ,
expected : false ,
2016-09-21 00:15:09 +01:00
} ,
{
application : marathon . Application {
2016-10-06 17:42:19 +02:00
ID : "foo2" ,
2016-09-21 00:15:09 +01:00
Labels : & map [ string ] string {
"traefik.tags" : "valid" ,
} ,
} ,
filteredTasks : [ ] marathon . Task {
{
2016-10-06 17:42:19 +02:00
AppID : "foo2" ,
2016-09-21 00:15:09 +01:00
} ,
} ,
2016-10-06 17:42:19 +02:00
marathonLBCompatibility : false ,
expected : true ,
} ,
{
application : marathon . Application {
ID : "foo3" ,
Labels : & map [ string ] string {
"HAPROXY_GROUP" : "valid" ,
"traefik.tags" : "notvalid" ,
} ,
} ,
filteredTasks : [ ] marathon . Task {
{
AppID : "foo3" ,
} ,
} ,
marathonLBCompatibility : true ,
expected : true ,
2016-09-21 00:15:09 +01:00
} ,
}
for _ , c := range cases {
2016-10-06 17:42:19 +02:00
provider := & Marathon {
MarathonLBCompatibility : c . marathonLBCompatibility ,
}
constraint , _ := types . NewConstraint ( "tag==valid" )
2016-11-09 19:27:04 +01:00
provider . Constraints = types . Constraints { constraint }
2016-09-21 00:15:09 +01:00
actual := provider . applicationFilter ( c . application , c . filteredTasks )
if actual != c . expected {
t . Fatalf ( "expected %v, got %v: %v" , c . expected , actual , c . application )
}
}
}
func TestMarathonTaskConstraints ( t * testing . T ) {
cases := [ ] struct {
2016-10-06 17:42:19 +02:00
applications [ ] marathon . Application
filteredTask marathon . Task
expected bool
marathonLBCompatibility bool
2016-09-21 00:15:09 +01:00
} {
{
applications : [ ] marathon . Application {
2016-09-21 00:41:34 +01:00
{
2016-09-21 00:15:09 +01:00
ID : "bar1" ,
Labels : & map [ string ] string { } ,
2016-09-21 00:41:34 +01:00
} , {
2016-09-21 00:15:09 +01:00
ID : "foo1" ,
Labels : & map [ string ] string {
"traefik.tags" : "other" ,
} ,
} ,
} ,
filteredTask : marathon . Task {
AppID : "foo1" ,
Ports : [ ] int { 80 } ,
} ,
2016-10-06 17:42:19 +02:00
marathonLBCompatibility : false ,
expected : false ,
2016-09-21 00:15:09 +01:00
} ,
{
applications : [ ] marathon . Application {
2016-09-21 00:41:34 +01:00
{
2016-09-21 00:15:09 +01:00
ID : "foo2" ,
Labels : & map [ string ] string {
"traefik.tags" : "valid" ,
} ,
} ,
} ,
filteredTask : marathon . Task {
AppID : "foo2" ,
Ports : [ ] int { 80 } ,
} ,
2016-10-06 17:42:19 +02:00
marathonLBCompatibility : false ,
expected : true ,
} ,
{
applications : [ ] marathon . Application {
{
ID : "foo3" ,
Labels : & map [ string ] string {
"HAPROXY_GROUP" : "valid" ,
"traefik.tags" : "notvalid" ,
} ,
} , {
ID : "foo4" ,
Labels : & map [ string ] string {
"HAPROXY_GROUP" : "notvalid" ,
"traefik.tags" : "valid" ,
} ,
} ,
} ,
filteredTask : marathon . Task {
AppID : "foo3" ,
Ports : [ ] int { 80 } ,
} ,
marathonLBCompatibility : true ,
expected : true ,
2016-09-21 00:15:09 +01:00
} ,
}
for _ , c := range cases {
2016-10-06 17:42:19 +02:00
provider := & Marathon {
MarathonLBCompatibility : c . marathonLBCompatibility ,
}
constraint , _ := types . NewConstraint ( "tag==valid" )
2016-11-09 19:27:04 +01:00
provider . Constraints = types . Constraints { constraint }
2016-09-21 00:15:09 +01:00
apps := new ( marathon . Applications )
apps . Apps = c . applications
actual := provider . taskFilter ( c . filteredTask , apps , true )
if actual != c . expected {
t . Fatalf ( "expected %v, got %v: %v" , c . expected , actual , c . filteredTask )
}
}
}
2015-11-13 11:50:32 +01:00
func TestMarathonApplicationFilter ( t * testing . T ) {
cases := [ ] struct {
application marathon . Application
filteredTasks [ ] marathon . Task
expected bool
} {
{
2016-09-20 09:44:32 +01:00
application : marathon . Application {
Labels : & map [ string ] string { } ,
} ,
2015-11-13 11:50:32 +01:00
filteredTasks : [ ] marathon . Task { } ,
expected : false ,
} ,
{
application : marathon . Application {
2016-06-20 17:11:07 +02:00
ID : "test" ,
Labels : & map [ string ] string { } ,
2015-11-13 11:50:32 +01:00
} ,
filteredTasks : [ ] marathon . Task { } ,
expected : false ,
} ,
{
application : marathon . Application {
2016-06-20 17:11:07 +02:00
ID : "foo" ,
Labels : & map [ string ] string { } ,
2015-11-13 11:50:32 +01:00
} ,
filteredTasks : [ ] marathon . Task {
{
AppID : "bar" ,
} ,
} ,
expected : false ,
} ,
{
application : marathon . Application {
2016-06-20 17:11:07 +02:00
ID : "foo" ,
Labels : & map [ string ] string { } ,
2015-11-13 11:50:32 +01:00
} ,
filteredTasks : [ ] marathon . Task {
{
AppID : "foo" ,
} ,
} ,
expected : true ,
} ,
}
2016-09-20 09:44:32 +01:00
provider := & Marathon { }
2015-11-13 11:50:32 +01:00
for _ , c := range cases {
2016-09-20 09:44:32 +01:00
actual := provider . applicationFilter ( c . application , c . filteredTasks )
2015-11-13 11:50:32 +01:00
if actual != c . expected {
t . Fatalf ( "expected %v, got %v" , c . expected , actual )
}
}
}
func TestMarathonGetPort ( t * testing . T ) {
provider := & Marathon { }
cases := [ ] struct {
2015-12-05 10:59:01 -08:00
applications [ ] marathon . Application
task marathon . Task
expected string
2015-11-13 11:50:32 +01:00
} {
{
2015-12-05 10:59:01 -08:00
applications : [ ] marathon . Application { } ,
task : marathon . Task { } ,
expected : "" ,
} ,
{
applications : [ ] marathon . Application {
{
2016-06-20 17:11:07 +02:00
ID : "test1" ,
Labels : & map [ string ] string { } ,
2015-12-05 10:59:01 -08:00
} ,
} ,
task : marathon . Task {
AppID : "test2" ,
} ,
2015-11-13 11:50:32 +01:00
expected : "" ,
} ,
{
2015-12-05 10:59:01 -08:00
applications : [ ] marathon . Application {
{
2016-06-20 17:11:07 +02:00
ID : "test1" ,
Labels : & map [ string ] string { } ,
2015-12-05 10:59:01 -08:00
} ,
} ,
2015-11-13 11:50:32 +01:00
task : marathon . Task {
2015-12-05 10:59:01 -08:00
AppID : "test1" ,
2015-11-13 11:50:32 +01:00
Ports : [ ] int { 80 } ,
} ,
expected : "80" ,
} ,
{
2015-12-05 10:59:01 -08:00
applications : [ ] marathon . Application {
{
2016-10-27 15:49:34 +02:00
ID : "multiple-ports-take-first" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string { } ,
2015-12-05 10:59:01 -08:00
} ,
} ,
2015-11-13 11:50:32 +01:00
task : marathon . Task {
2016-10-27 15:49:34 +02:00
AppID : "multiple-ports-take-first" ,
2015-11-13 11:50:32 +01:00
Ports : [ ] int { 80 , 443 } ,
} ,
expected : "80" ,
} ,
2015-12-05 10:59:01 -08:00
{
applications : [ ] marathon . Application {
{
ID : "specify-port-number" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-12-05 10:59:01 -08:00
"traefik.port" : "443" ,
} ,
} ,
} ,
task : marathon . Task {
AppID : "specify-port-number" ,
Ports : [ ] int { 80 , 443 } ,
} ,
expected : "443" ,
} ,
{
applications : [ ] marathon . Application {
{
ID : "specify-port-index" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-12-05 10:59:01 -08:00
"traefik.portIndex" : "1" ,
} ,
} ,
} ,
task : marathon . Task {
AppID : "specify-port-index" ,
Ports : [ ] int { 80 , 443 } ,
} ,
expected : "443" ,
2017-01-31 12:48:21 -02:00
} , {
applications : [ ] marathon . Application {
{
ID : "application-with-port" ,
Ports : [ ] int { 9999 } ,
Labels : & map [ string ] string { } ,
} ,
} ,
task : marathon . Task {
AppID : "application-with-port" ,
Ports : [ ] int { 7777 } ,
} ,
expected : "7777" ,
2015-12-05 10:59:01 -08:00
} ,
2015-11-13 11:50:32 +01:00
}
for _ , c := range cases {
2015-12-05 10:59:01 -08:00
actual := provider . getPort ( c . task , c . applications )
2015-11-13 11:50:32 +01:00
if actual != c . expected {
t . Fatalf ( "expected %q, got %q" , c . expected , actual )
}
}
}
func TestMarathonGetWeigh ( t * testing . T ) {
provider := & Marathon { }
applications := [ ] struct {
applications [ ] marathon . Application
task marathon . Task
expected string
} {
{
applications : [ ] marathon . Application { } ,
task : marathon . Task { } ,
expected : "0" ,
} ,
{
applications : [ ] marathon . Application {
{
ID : "test1" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-11-13 11:50:32 +01:00
"traefik.weight" : "10" ,
} ,
} ,
} ,
task : marathon . Task {
AppID : "test2" ,
} ,
expected : "0" ,
} ,
{
applications : [ ] marathon . Application {
{
ID : "test" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-11-13 11:50:32 +01:00
"traefik.test" : "10" ,
} ,
} ,
} ,
task : marathon . Task {
AppID : "test" ,
} ,
expected : "0" ,
} ,
{
applications : [ ] marathon . Application {
{
ID : "test" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-11-13 11:50:32 +01:00
"traefik.weight" : "10" ,
} ,
} ,
} ,
task : marathon . Task {
AppID : "test" ,
} ,
expected : "10" ,
} ,
}
for _ , a := range applications {
actual := provider . getWeight ( a . task , a . applications )
if actual != a . expected {
t . Fatalf ( "expected %q, got %q" , a . expected , actual )
}
}
}
func TestMarathonGetDomain ( t * testing . T ) {
provider := & Marathon {
Domain : "docker.localhost" ,
}
applications := [ ] struct {
application marathon . Application
expected string
} {
{
2016-06-20 17:11:07 +02:00
application : marathon . Application {
Labels : & map [ string ] string { } } ,
expected : "docker.localhost" ,
2015-11-13 11:50:32 +01:00
} ,
{
application : marathon . Application {
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-11-13 11:50:32 +01:00
"traefik.domain" : "foo.bar" ,
} ,
} ,
expected : "foo.bar" ,
} ,
}
for _ , a := range applications {
actual := provider . getDomain ( a . application )
if actual != a . expected {
t . Fatalf ( "expected %q, got %q" , a . expected , actual )
}
}
}
func TestMarathonGetProtocol ( t * testing . T ) {
provider := & Marathon { }
applications := [ ] struct {
applications [ ] marathon . Application
task marathon . Task
expected string
} {
{
applications : [ ] marathon . Application { } ,
task : marathon . Task { } ,
expected : "http" ,
} ,
{
applications : [ ] marathon . Application {
{
ID : "test1" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-11-13 11:50:32 +01:00
"traefik.protocol" : "https" ,
} ,
} ,
} ,
task : marathon . Task {
AppID : "test2" ,
} ,
expected : "http" ,
} ,
{
applications : [ ] marathon . Application {
{
ID : "test" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-11-13 11:50:32 +01:00
"traefik.foo" : "bar" ,
} ,
} ,
} ,
task : marathon . Task {
AppID : "test" ,
} ,
expected : "http" ,
} ,
{
applications : [ ] marathon . Application {
{
ID : "test" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2015-11-13 11:50:32 +01:00
"traefik.protocol" : "https" ,
} ,
} ,
} ,
task : marathon . Task {
AppID : "test" ,
} ,
expected : "https" ,
} ,
}
for _ , a := range applications {
actual := provider . getProtocol ( a . task , a . applications )
if actual != a . expected {
t . Fatalf ( "expected %q, got %q" , a . expected , actual )
}
}
}
func TestMarathonGetPassHostHeader ( t * testing . T ) {
provider := & Marathon { }
applications := [ ] struct {
application marathon . Application
expected string
} {
{
2016-06-20 17:11:07 +02:00
application : marathon . Application {
Labels : & map [ string ] string { } } ,
expected : "true" ,
2015-11-13 11:50:32 +01:00
} ,
{
application : marathon . Application {
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2016-05-10 07:43:24 -04:00
"traefik.frontend.passHostHeader" : "false" ,
2015-11-13 11:50:32 +01:00
} ,
} ,
2016-05-10 07:43:24 -04:00
expected : "false" ,
2015-11-13 11:50:32 +01:00
} ,
}
for _ , a := range applications {
actual := provider . getPassHostHeader ( a . application )
if actual != a . expected {
t . Fatalf ( "expected %q, got %q" , a . expected , actual )
}
}
}
2016-02-01 11:07:05 +01:00
func TestMarathonGetEntryPoints ( t * testing . T ) {
provider := & Marathon { }
applications := [ ] struct {
application marathon . Application
expected [ ] string
} {
{
2016-06-20 17:11:07 +02:00
application : marathon . Application {
Labels : & map [ string ] string { } } ,
expected : [ ] string { } ,
2016-02-01 11:07:05 +01:00
} ,
{
application : marathon . Application {
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2016-02-01 11:07:05 +01:00
"traefik.frontend.entryPoints" : "http,https" ,
} ,
} ,
expected : [ ] string { "http" , "https" } ,
} ,
}
for _ , a := range applications {
actual := provider . getEntryPoints ( a . application )
if ! reflect . DeepEqual ( actual , a . expected ) {
t . Fatalf ( "expected %#v, got %#v" , a . expected , actual )
}
}
}
2016-03-27 01:05:17 +01:00
func TestMarathonGetFrontendRule ( t * testing . T ) {
2015-11-13 11:50:32 +01:00
applications := [ ] struct {
2016-10-06 17:42:19 +02:00
application marathon . Application
expected string
marathonLBCompatibility bool
2015-11-13 11:50:32 +01:00
} {
{
2016-06-20 17:11:07 +02:00
application : marathon . Application {
Labels : & map [ string ] string { } } ,
2016-10-06 17:42:19 +02:00
marathonLBCompatibility : true ,
expected : "Host:.docker.localhost" ,
2015-11-13 11:50:32 +01:00
} ,
{
application : marathon . Application {
2016-10-06 17:42:19 +02:00
ID : "test" ,
Labels : & map [ string ] string {
"HAPROXY_0_VHOST" : "foo.bar" ,
} ,
2015-11-13 11:50:32 +01:00
} ,
2016-10-06 17:42:19 +02:00
marathonLBCompatibility : false ,
expected : "Host:test.docker.localhost" ,
2015-11-13 11:50:32 +01:00
} ,
{
application : marathon . Application {
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2016-03-27 01:05:17 +01:00
"traefik.frontend.rule" : "Host:foo.bar" ,
2016-10-06 17:42:19 +02:00
"HAPROXY_0_VHOST" : "notvalid" ,
} ,
} ,
marathonLBCompatibility : true ,
expected : "Host:foo.bar" ,
} ,
{
application : marathon . Application {
Labels : & map [ string ] string {
"HAPROXY_0_VHOST" : "foo.bar" ,
2015-11-13 11:50:32 +01:00
} ,
} ,
2016-10-06 17:42:19 +02:00
marathonLBCompatibility : true ,
expected : "Host:foo.bar" ,
2015-11-13 11:50:32 +01:00
} ,
}
for _ , a := range applications {
2016-10-06 17:42:19 +02:00
provider := & Marathon {
Domain : "docker.localhost" ,
MarathonLBCompatibility : a . marathonLBCompatibility ,
}
2015-11-13 11:50:32 +01:00
actual := provider . getFrontendRule ( a . application )
if actual != a . expected {
t . Fatalf ( "expected %q, got %q" , a . expected , actual )
}
}
}
2016-01-20 18:55:10 +00:00
func TestMarathonGetBackend ( t * testing . T ) {
provider := & Marathon { }
applications := [ ] struct {
application marathon . Application
expected string
} {
{
application : marathon . Application {
ID : "foo" ,
2016-06-20 17:11:07 +02:00
Labels : & map [ string ] string {
2016-01-20 18:55:10 +00:00
"traefik.backend" : "bar" ,
} ,
} ,
expected : "bar" ,
} ,
}
for _ , a := range applications {
2016-02-12 14:45:36 +01:00
actual := provider . getFrontendBackend ( a . application )
2016-01-20 18:55:10 +00:00
if actual != a . expected {
t . Fatalf ( "expected %q, got %q" , a . expected , actual )
}
}
}
2016-11-28 08:59:08 -05:00
func TestMarathonGetSubDomain ( t * testing . T ) {
providerGroups := & Marathon { GroupsAsSubDomains : true }
providerNoGroups := & Marathon { GroupsAsSubDomains : false }
apps := [ ] struct {
path string
expected string
provider * Marathon
} {
{ "/test" , "test" , providerNoGroups } ,
{ "/test" , "test" , providerGroups } ,
{ "/a/b/c/d" , "d.c.b.a" , providerGroups } ,
{ "/b/a/d/c" , "c.d.a.b" , providerGroups } ,
{ "/d/c/b/a" , "a.b.c.d" , providerGroups } ,
{ "/c/d/a/b" , "b.a.d.c" , providerGroups } ,
{ "/a/b/c/d" , "a-b-c-d" , providerNoGroups } ,
{ "/b/a/d/c" , "b-a-d-c" , providerNoGroups } ,
{ "/d/c/b/a" , "d-c-b-a" , providerNoGroups } ,
{ "/c/d/a/b" , "c-d-a-b" , providerNoGroups } ,
}
for _ , a := range apps {
actual := a . provider . getSubDomain ( a . path )
if actual != a . expected {
t . Errorf ( "expected %q, got %q" , a . expected , actual )
}
}
}