2017-04-17 13:50:02 +03:00
package consul
2016-02-02 20:03:40 +03:00
import (
2016-06-20 20:13:22 +03:00
"sort"
2016-02-02 20:03:40 +03:00
"testing"
2017-05-08 20:46:53 +03:00
"text/template"
2016-02-02 20:03:40 +03:00
2017-06-18 12:38:35 +03:00
"github.com/BurntSushi/ty/fun"
2016-02-24 18:43:39 +03:00
"github.com/containous/traefik/types"
2016-02-02 20:03:40 +03:00
"github.com/hashicorp/consul/api"
2017-10-12 18:50:03 +03:00
"github.com/stretchr/testify/assert"
2016-02-02 20:03:40 +03:00
)
2016-03-27 03:05:17 +03:00
func TestConsulCatalogGetFrontendRule ( t * testing . T ) {
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2016-04-12 10:49:37 +03:00
service serviceUpdate
2016-02-02 20:03:40 +03:00
expected string
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should return default host foo.localhost" ,
2016-04-12 10:49:37 +03:00
service : serviceUpdate {
ServiceName : "foo" ,
Attributes : [ ] string { } ,
} ,
2016-03-27 03:05:17 +03:00
expected : "Host:foo.localhost" ,
2016-02-02 20:03:40 +03:00
} ,
2016-04-12 10:49:37 +03:00
{
2017-11-13 14:14:02 +03:00
desc : "Should return host *.example.com" ,
2016-04-12 10:49:37 +03:00
service : serviceUpdate {
ServiceName : "foo" ,
Attributes : [ ] string {
"traefik.frontend.rule=Host:*.example.com" ,
} ,
} ,
expected : "Host:*.example.com" ,
} ,
2017-05-08 20:46:53 +03:00
{
2017-11-13 14:14:02 +03:00
desc : "Should return host foo.example.com" ,
2017-05-08 20:46:53 +03:00
service : serviceUpdate {
ServiceName : "foo" ,
Attributes : [ ] string {
"traefik.frontend.rule=Host:{{.ServiceName}}.example.com" ,
} ,
} ,
expected : "Host:foo.example.com" ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should return path prefix /bar" ,
2017-05-08 20:46:53 +03:00
service : serviceUpdate {
ServiceName : "foo" ,
Attributes : [ ] string {
"traefik.frontend.rule=PathPrefix:{{getTag \"contextPath\" .Attributes \"/\"}}" ,
"contextPath=/bar" ,
} ,
} ,
expected : "PathPrefix:/bar" ,
} ,
2016-02-02 20:03:40 +03:00
}
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
2018-01-02 12:52:03 +03:00
provider := & CatalogProvider {
Domain : "localhost" ,
Prefix : "traefik" ,
FrontEndRule : "Host:{{.ServiceName}}.{{.Domain}}" ,
frontEndRuleTemplate : template . New ( "consul catalog frontend rule" ) ,
}
provider . setupFrontEndTemplate ( )
2017-11-13 14:14:02 +03:00
actual := provider . getFrontendRule ( test . service )
assert . Equal ( t , test . expected , actual )
} )
2017-05-08 20:46:53 +03:00
}
}
func TestConsulCatalogGetTag ( t * testing . T ) {
provider := & CatalogProvider {
Domain : "localhost" ,
Prefix : "traefik" ,
}
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2017-05-08 20:46:53 +03:00
tags [ ] string
key string
defaultValue string
expected string
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should return value of foo.bar key" ,
2017-05-08 20:46:53 +03:00
tags : [ ] string {
"foo.bar=random" ,
"traefik.backend.weight=42" ,
"management" ,
} ,
key : "foo.bar" ,
defaultValue : "0" ,
expected : "random" ,
} ,
}
2017-11-13 14:14:02 +03:00
assert . Equal ( t , true , provider . hasTag ( "management" , [ ] string { "management" } ) )
assert . Equal ( t , true , provider . hasTag ( "management" , [ ] string { "management=yes" } ) )
2017-05-08 20:46:53 +03:00
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
2017-05-08 20:46:53 +03:00
2017-11-13 14:14:02 +03:00
actual := provider . getTag ( test . key , test . tags , test . defaultValue )
assert . Equal ( t , test . expected , actual )
} )
2016-04-12 10:49:37 +03:00
}
}
func TestConsulCatalogGetAttribute ( t * testing . T ) {
2017-04-17 13:50:02 +03:00
provider := & CatalogProvider {
2016-04-12 10:49:37 +03:00
Domain : "localhost" ,
2017-04-24 16:09:28 +03:00
Prefix : "traefik" ,
2016-04-12 10:49:37 +03:00
}
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2016-04-12 10:49:37 +03:00
tags [ ] string
key string
defaultValue string
expected string
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should return tag value 42" ,
2016-04-12 10:49:37 +03:00
tags : [ ] string {
"foo.bar=ramdom" ,
"traefik.backend.weight=42" ,
} ,
key : "backend.weight" ,
2016-11-23 16:49:55 +03:00
defaultValue : "0" ,
2016-04-12 10:49:37 +03:00
expected : "42" ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should return tag default value 0" ,
2016-04-12 10:49:37 +03:00
tags : [ ] string {
"foo.bar=ramdom" ,
"traefik.backend.wei=42" ,
} ,
key : "backend.weight" ,
2016-11-23 16:49:55 +03:00
defaultValue : "0" ,
expected : "0" ,
2016-04-12 10:49:37 +03:00
} ,
}
2017-11-13 14:14:02 +03:00
assert . Equal ( t , provider . Prefix + ".foo" , provider . getPrefixedName ( "foo" ) )
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
2017-05-08 20:46:53 +03:00
2017-11-13 14:14:02 +03:00
actual := provider . getAttribute ( test . key , test . tags , test . defaultValue )
assert . Equal ( t , test . expected , actual )
} )
2017-05-08 20:46:53 +03:00
}
}
func TestConsulCatalogGetAttributeWithEmptyPrefix ( t * testing . T ) {
provider := & CatalogProvider {
Domain : "localhost" ,
Prefix : "" ,
}
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2017-05-08 20:46:53 +03:00
tags [ ] string
key string
defaultValue string
expected string
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should return tag value 42" ,
2017-05-08 20:46:53 +03:00
tags : [ ] string {
"foo.bar=ramdom" ,
"backend.weight=42" ,
} ,
key : "backend.weight" ,
defaultValue : "0" ,
expected : "42" ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should return default value 0" ,
2017-05-08 20:46:53 +03:00
tags : [ ] string {
"foo.bar=ramdom" ,
"backend.wei=42" ,
} ,
key : "backend.weight" ,
defaultValue : "0" ,
expected : "0" ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should return for.bar key value random" ,
2017-05-08 20:46:53 +03:00
tags : [ ] string {
"foo.bar=ramdom" ,
"backend.wei=42" ,
} ,
key : "foo.bar" ,
defaultValue : "random" ,
expected : "ramdom" ,
} ,
}
2017-11-13 14:14:02 +03:00
assert . Equal ( t , "foo" , provider . getPrefixedName ( "foo" ) )
2017-05-08 20:46:53 +03:00
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
actual := provider . getAttribute ( test . key , test . tags , test . defaultValue )
assert . Equal ( t , test . expected , actual )
} )
2016-02-02 20:03:40 +03:00
}
}
2016-04-15 10:56:06 +03:00
func TestConsulCatalogGetBackendAddress ( t * testing . T ) {
2017-04-17 13:50:02 +03:00
provider := & CatalogProvider {
2016-04-15 10:56:06 +03:00
Domain : "localhost" ,
2017-04-24 16:09:28 +03:00
Prefix : "traefik" ,
2016-04-15 10:56:06 +03:00
}
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2016-04-15 10:56:06 +03:00
node * api . ServiceEntry
expected string
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should return the address of the service" ,
2016-04-15 10:56:06 +03:00
node : & api . ServiceEntry {
Node : & api . Node {
Address : "10.1.0.1" ,
} ,
Service : & api . AgentService {
Address : "10.2.0.1" ,
} ,
} ,
expected : "10.2.0.1" ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should return the address of the node" ,
2016-04-15 10:56:06 +03:00
node : & api . ServiceEntry {
Node : & api . Node {
Address : "10.1.0.1" ,
} ,
Service : & api . AgentService {
Address : "" ,
} ,
} ,
expected : "10.1.0.1" ,
} ,
}
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
actual := provider . getBackendAddress ( test . node )
assert . Equal ( t , test . expected , actual )
} )
2016-04-15 10:56:06 +03:00
}
}
func TestConsulCatalogGetBackendName ( t * testing . T ) {
2017-04-17 13:50:02 +03:00
provider := & CatalogProvider {
2016-04-15 10:56:06 +03:00
Domain : "localhost" ,
2017-04-24 16:09:28 +03:00
Prefix : "traefik" ,
2016-04-15 10:56:06 +03:00
}
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2016-04-15 10:56:06 +03:00
node * api . ServiceEntry
expected string
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should create backend name without tags" ,
2016-04-15 10:56:06 +03:00
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { } ,
} ,
} ,
expected : "api--10-0-0-1--80--0" ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should create backend name with multiple tags" ,
2016-04-15 10:56:06 +03:00
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { "traefik.weight=42" , "traefik.enable=true" } ,
} ,
} ,
expected : "api--10-0-0-1--80--traefik-weight-42--traefik-enable-true--1" ,
} ,
2016-05-02 17:14:21 +03:00
{
2017-11-13 14:14:02 +03:00
desc : "Should create backend name with one tag" ,
2016-05-02 17:14:21 +03:00
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { "a funny looking tag" } ,
} ,
} ,
expected : "api--10-0-0-1--80--a-funny-looking-tag--2" ,
} ,
2016-04-15 10:56:06 +03:00
}
2017-11-13 14:14:02 +03:00
for i , test := range testCases {
test := test
i := i
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
actual := provider . getBackendName ( test . node , i )
assert . Equal ( t , test . expected , actual )
} )
2016-04-15 10:56:06 +03:00
}
}
2016-02-02 20:03:40 +03:00
func TestConsulCatalogBuildConfig ( t * testing . T ) {
2017-04-17 13:50:02 +03:00
provider := & CatalogProvider {
2017-05-08 20:46:53 +03:00
Domain : "localhost" ,
Prefix : "traefik" ,
2017-08-25 18:32:03 +03:00
ExposedByDefault : false ,
2017-05-08 20:46:53 +03:00
FrontEndRule : "Host:{{.ServiceName}}.{{.Domain}}" ,
frontEndRuleTemplate : template . New ( "consul catalog frontend rule" ) ,
2016-02-02 20:03:40 +03:00
}
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2016-02-02 20:03:40 +03:00
nodes [ ] catalogUpdate
expectedFrontends map [ string ] * types . Frontend
expectedBackends map [ string ] * types . Backend
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should build config of nothing" ,
2016-02-02 20:03:40 +03:00
nodes : [ ] catalogUpdate { } ,
expectedFrontends : map [ string ] * types . Frontend { } ,
expectedBackends : map [ string ] * types . Backend { } ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should build config with no frontend and backend" ,
2016-02-02 20:03:40 +03:00
nodes : [ ] catalogUpdate {
{
2016-04-12 10:49:37 +03:00
Service : & serviceUpdate {
ServiceName : "test" ,
} ,
2016-02-02 20:03:40 +03:00
} ,
} ,
expectedFrontends : map [ string ] * types . Frontend { } ,
expectedBackends : map [ string ] * types . Backend { } ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should build config who contains one frontend and one backend" ,
2016-02-02 20:03:40 +03:00
nodes : [ ] catalogUpdate {
{
2016-04-12 10:49:37 +03:00
Service : & serviceUpdate {
ServiceName : "test" ,
Attributes : [ ] string {
"traefik.backend.loadbalancer=drr" ,
"traefik.backend.circuitbreaker=NetworkErrorRatio() > 0.5" ,
"random.foo=bar" ,
2016-08-25 06:46:47 +03:00
"traefik.backend.maxconn.amount=1000" ,
"traefik.backend.maxconn.extractorfunc=client.ip" ,
2017-09-07 16:28:02 +03:00
"traefik.frontend.auth.basic=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" ,
2016-04-12 10:49:37 +03:00
} ,
} ,
2016-02-02 20:03:40 +03:00
Nodes : [ ] * api . ServiceEntry {
{
Service : & api . AgentService {
Service : "test" ,
2016-04-08 16:08:28 +03:00
Address : "127.0.0.1" ,
2016-02-02 20:03:40 +03:00
Port : 80 ,
2016-04-12 10:49:37 +03:00
Tags : [ ] string {
"traefik.backend.weight=42" ,
"random.foo=bar" ,
"traefik.backend.passHostHeader=true" ,
"traefik.protocol=https" ,
} ,
2016-02-02 20:03:40 +03:00
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.1" ,
} ,
} ,
} ,
} ,
} ,
expectedFrontends : map [ string ] * types . Frontend {
"frontend-test" : {
2016-05-10 14:43:24 +03:00
Backend : "backend-test" ,
PassHostHeader : true ,
2016-02-02 20:03:40 +03:00
Routes : map [ string ] types . Route {
"route-host-test" : {
2016-03-27 03:05:17 +03:00
Rule : "Host:test.localhost" ,
2016-02-02 20:03:40 +03:00
} ,
} ,
2017-09-07 16:28:02 +03:00
BasicAuth : [ ] string { "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" , "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" } ,
2016-02-02 20:03:40 +03:00
} ,
} ,
expectedBackends : map [ string ] * types . Backend {
"backend-test" : {
Servers : map [ string ] types . Server {
2016-04-15 10:56:06 +03:00
"test--127-0-0-1--80--traefik-backend-weight-42--random-foo-bar--traefik-backend-passHostHeader-true--traefik-protocol-https--0" : {
2016-04-12 10:49:37 +03:00
URL : "https://127.0.0.1:80" ,
Weight : 42 ,
2016-02-02 20:03:40 +03:00
} ,
} ,
2016-04-12 10:49:37 +03:00
CircuitBreaker : & types . CircuitBreaker {
Expression : "NetworkErrorRatio() > 0.5" ,
} ,
LoadBalancer : & types . LoadBalancer {
Method : "drr" ,
} ,
2016-08-25 06:46:47 +03:00
MaxConn : & types . MaxConn {
Amount : 1000 ,
ExtractorFunc : "client.ip" ,
} ,
2016-02-02 20:03:40 +03:00
} ,
} ,
} ,
}
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
actualConfig := provider . buildConfig ( test . nodes )
assert . Equal ( t , test . expectedBackends , actualConfig . Backends )
assert . Equal ( t , test . expectedFrontends , actualConfig . Frontends )
} )
2016-02-02 20:03:40 +03:00
}
}
2016-06-20 20:13:22 +03:00
func TestConsulCatalogNodeSorter ( t * testing . T ) {
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2016-06-20 20:13:22 +03:00
nodes [ ] * api . ServiceEntry
expected [ ] * api . ServiceEntry
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should sort nothing" ,
2016-06-20 20:13:22 +03:00
nodes : [ ] * api . ServiceEntry { } ,
expected : [ ] * api . ServiceEntry { } ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should sort by node address" ,
2016-06-20 20:13:22 +03:00
nodes : [ ] * api . ServiceEntry {
{
Service : & api . AgentService {
Service : "foo" ,
Address : "127.0.0.1" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.1" ,
} ,
} ,
} ,
expected : [ ] * api . ServiceEntry {
{
Service : & api . AgentService {
Service : "foo" ,
Address : "127.0.0.1" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.1" ,
} ,
} ,
} ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should sort by service name" ,
2016-06-20 20:13:22 +03:00
nodes : [ ] * api . ServiceEntry {
{
Service : & api . AgentService {
Service : "foo" ,
Address : "127.0.0.2" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.2" ,
} ,
} ,
{
Service : & api . AgentService {
Service : "bar" ,
Address : "127.0.0.2" ,
Port : 81 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.2" ,
} ,
} ,
{
Service : & api . AgentService {
Service : "foo" ,
Address : "127.0.0.1" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.1" ,
} ,
} ,
{
Service : & api . AgentService {
Service : "bar" ,
Address : "127.0.0.2" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.2" ,
} ,
} ,
} ,
expected : [ ] * api . ServiceEntry {
{
Service : & api . AgentService {
Service : "bar" ,
Address : "127.0.0.2" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.2" ,
} ,
} ,
{
Service : & api . AgentService {
Service : "bar" ,
Address : "127.0.0.2" ,
Port : 81 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.2" ,
} ,
} ,
{
Service : & api . AgentService {
Service : "foo" ,
Address : "127.0.0.1" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.1" ,
} ,
} ,
{
Service : & api . AgentService {
Service : "foo" ,
Address : "127.0.0.2" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.2" ,
} ,
} ,
} ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should sort by node address" ,
2016-06-20 20:13:22 +03:00
nodes : [ ] * api . ServiceEntry {
{
Service : & api . AgentService {
Service : "foo" ,
Address : "" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.2" ,
} ,
} ,
{
Service : & api . AgentService {
Service : "foo" ,
Address : "" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.1" ,
} ,
} ,
} ,
expected : [ ] * api . ServiceEntry {
{
Service : & api . AgentService {
Service : "foo" ,
Address : "" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.1" ,
} ,
} ,
{
Service : & api . AgentService {
Service : "foo" ,
Address : "" ,
Port : 80 ,
} ,
Node : & api . Node {
Node : "localhost" ,
Address : "127.0.0.2" ,
} ,
} ,
} ,
} ,
}
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
sort . Sort ( nodeSorter ( test . nodes ) )
actual := test . nodes
assert . Equal ( t , test . expected , actual )
} )
2016-06-20 20:13:22 +03:00
}
}
2017-06-18 12:38:35 +03:00
func TestConsulCatalogGetChangedKeys ( t * testing . T ) {
type Input struct {
2017-09-08 21:50:04 +03:00
currState map [ string ] Service
prevState map [ string ] Service
2017-06-18 12:38:35 +03:00
}
type Output struct {
addedKeys [ ] string
removedKeys [ ] string
}
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
desc string
2017-06-18 12:38:35 +03:00
input Input
output Output
} {
{
2017-11-13 14:14:02 +03:00
desc : "Should add 0 services and removed 0" ,
2017-06-18 12:38:35 +03:00
input : Input {
2017-09-08 21:50:04 +03:00
currState : map [ string ] Service {
"foo-service" : { Name : "v1" } ,
"bar-service" : { Name : "v1" } ,
"baz-service" : { Name : "v1" } ,
"qux-service" : { Name : "v1" } ,
"quux-service" : { Name : "v1" } ,
"quuz-service" : { Name : "v1" } ,
"corge-service" : { Name : "v1" } ,
"grault-service" : { Name : "v1" } ,
"garply-service" : { Name : "v1" } ,
"waldo-service" : { Name : "v1" } ,
"fred-service" : { Name : "v1" } ,
"plugh-service" : { Name : "v1" } ,
"xyzzy-service" : { Name : "v1" } ,
"thud-service" : { Name : "v1" } ,
} ,
prevState : map [ string ] Service {
"foo-service" : { Name : "v1" } ,
"bar-service" : { Name : "v1" } ,
"baz-service" : { Name : "v1" } ,
"qux-service" : { Name : "v1" } ,
"quux-service" : { Name : "v1" } ,
"quuz-service" : { Name : "v1" } ,
"corge-service" : { Name : "v1" } ,
"grault-service" : { Name : "v1" } ,
"garply-service" : { Name : "v1" } ,
"waldo-service" : { Name : "v1" } ,
"fred-service" : { Name : "v1" } ,
"plugh-service" : { Name : "v1" } ,
"xyzzy-service" : { Name : "v1" } ,
"thud-service" : { Name : "v1" } ,
2017-06-18 12:38:35 +03:00
} ,
} ,
output : Output {
addedKeys : [ ] string { } ,
removedKeys : [ ] string { } ,
} ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should add 3 services and removed 0" ,
2017-06-18 12:38:35 +03:00
input : Input {
2017-09-08 21:50:04 +03:00
currState : map [ string ] Service {
"foo-service" : { Name : "v1" } ,
"bar-service" : { Name : "v1" } ,
"baz-service" : { Name : "v1" } ,
"qux-service" : { Name : "v1" } ,
"quux-service" : { Name : "v1" } ,
"quuz-service" : { Name : "v1" } ,
"corge-service" : { Name : "v1" } ,
"grault-service" : { Name : "v1" } ,
"garply-service" : { Name : "v1" } ,
"waldo-service" : { Name : "v1" } ,
"fred-service" : { Name : "v1" } ,
"plugh-service" : { Name : "v1" } ,
"xyzzy-service" : { Name : "v1" } ,
"thud-service" : { Name : "v1" } ,
} ,
prevState : map [ string ] Service {
"foo-service" : { Name : "v1" } ,
"bar-service" : { Name : "v1" } ,
"baz-service" : { Name : "v1" } ,
"corge-service" : { Name : "v1" } ,
"grault-service" : { Name : "v1" } ,
"garply-service" : { Name : "v1" } ,
"waldo-service" : { Name : "v1" } ,
"fred-service" : { Name : "v1" } ,
"plugh-service" : { Name : "v1" } ,
"xyzzy-service" : { Name : "v1" } ,
"thud-service" : { Name : "v1" } ,
2017-06-18 12:38:35 +03:00
} ,
} ,
output : Output {
addedKeys : [ ] string { "qux-service" , "quux-service" , "quuz-service" } ,
removedKeys : [ ] string { } ,
} ,
} ,
{
2017-11-13 14:14:02 +03:00
desc : "Should add 2 services and removed 2" ,
2017-06-18 12:38:35 +03:00
input : Input {
2017-09-08 21:50:04 +03:00
currState : map [ string ] Service {
"foo-service" : { Name : "v1" } ,
"qux-service" : { Name : "v1" } ,
"quux-service" : { Name : "v1" } ,
"quuz-service" : { Name : "v1" } ,
"corge-service" : { Name : "v1" } ,
"grault-service" : { Name : "v1" } ,
"garply-service" : { Name : "v1" } ,
"waldo-service" : { Name : "v1" } ,
"fred-service" : { Name : "v1" } ,
"plugh-service" : { Name : "v1" } ,
"xyzzy-service" : { Name : "v1" } ,
"thud-service" : { Name : "v1" } ,
} ,
prevState : map [ string ] Service {
"foo-service" : { Name : "v1" } ,
"bar-service" : { Name : "v1" } ,
"baz-service" : { Name : "v1" } ,
"qux-service" : { Name : "v1" } ,
"quux-service" : { Name : "v1" } ,
"quuz-service" : { Name : "v1" } ,
"corge-service" : { Name : "v1" } ,
"waldo-service" : { Name : "v1" } ,
"fred-service" : { Name : "v1" } ,
"plugh-service" : { Name : "v1" } ,
"xyzzy-service" : { Name : "v1" } ,
"thud-service" : { Name : "v1" } ,
2017-06-18 12:38:35 +03:00
} ,
} ,
output : Output {
addedKeys : [ ] string { "grault-service" , "garply-service" } ,
removedKeys : [ ] string { "bar-service" , "baz-service" } ,
} ,
} ,
}
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
2017-06-18 12:38:35 +03:00
2017-11-13 14:14:02 +03:00
addedKeys , removedKeys := getChangedServiceKeys ( test . input . currState , test . input . prevState )
assert . Equal ( t , fun . Set ( test . output . addedKeys ) , fun . Set ( addedKeys ) , "Added keys comparison results: got %q, want %q" , addedKeys , test . output . addedKeys )
assert . Equal ( t , fun . Set ( test . output . removedKeys ) , fun . Set ( removedKeys ) , "Removed keys comparison results: got %q, want %q" , removedKeys , test . output . removedKeys )
} )
2017-06-18 12:38:35 +03:00
}
}
2017-08-25 18:32:03 +03:00
func TestConsulCatalogFilterEnabled ( t * testing . T ) {
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
2017-08-25 18:32:03 +03:00
desc string
exposedByDefault bool
node * api . ServiceEntry
expected bool
} {
{
desc : "exposed" ,
exposedByDefault : true ,
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { "" } ,
} ,
} ,
expected : true ,
} ,
{
desc : "exposed and tolerated by valid label value" ,
exposedByDefault : true ,
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { "" , "traefik.enable=true" } ,
} ,
} ,
expected : true ,
} ,
{
desc : "exposed and tolerated by invalid label value" ,
exposedByDefault : true ,
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { "" , "traefik.enable=bad" } ,
} ,
} ,
expected : true ,
} ,
{
desc : "exposed but overridden by label" ,
exposedByDefault : true ,
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { "" , "traefik.enable=false" } ,
} ,
} ,
expected : false ,
} ,
{
desc : "non-exposed" ,
exposedByDefault : false ,
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { "" } ,
} ,
} ,
expected : false ,
} ,
{
desc : "non-exposed but overridden by label" ,
exposedByDefault : false ,
node : & api . ServiceEntry {
Service : & api . AgentService {
Service : "api" ,
Address : "10.0.0.1" ,
Port : 80 ,
Tags : [ ] string { "" , "traefik.enable=true" } ,
} ,
} ,
expected : true ,
} ,
}
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
2017-08-25 18:32:03 +03:00
t . Parallel ( )
provider := & CatalogProvider {
Domain : "localhost" ,
Prefix : "traefik" ,
2017-11-13 14:14:02 +03:00
ExposedByDefault : test . exposedByDefault ,
2017-08-25 18:32:03 +03:00
}
2017-11-13 14:14:02 +03:00
actual := provider . nodeFilter ( "test" , test . node )
assert . Equal ( t , test . expected , actual )
2017-08-25 18:32:03 +03:00
} )
}
}
2017-09-07 16:28:02 +03:00
func TestConsulCatalogGetBasicAuth ( t * testing . T ) {
2017-11-13 14:14:02 +03:00
testCases := [ ] struct {
2017-09-07 16:28:02 +03:00
desc string
tags [ ] string
expected [ ] string
} {
{
desc : "label missing" ,
tags : [ ] string { } ,
expected : [ ] string { } ,
} ,
{
desc : "label existing" ,
tags : [ ] string {
"traefik.frontend.auth.basic=user:password" ,
} ,
expected : [ ] string { "user:password" } ,
} ,
}
2017-11-13 14:14:02 +03:00
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
2017-09-07 16:28:02 +03:00
t . Parallel ( )
provider := & CatalogProvider {
Prefix : "traefik" ,
}
2017-11-13 14:14:02 +03:00
actual := provider . getBasicAuth ( test . tags )
assert . Equal ( t , test . expected , actual )
2017-09-07 16:28:02 +03:00
} )
}
}
2017-10-12 18:50:03 +03:00
func TestConsulCatalogHasStickinessLabel ( t * testing . T ) {
testCases := [ ] struct {
desc string
tags [ ] string
expected bool
} {
{
desc : "label missing" ,
tags : [ ] string { } ,
expected : false ,
} ,
{
desc : "stickiness=true" ,
tags : [ ] string {
2017-10-16 18:38:03 +03:00
types . LabelBackendLoadbalancerStickiness + "=true" ,
2017-10-12 18:50:03 +03:00
} ,
expected : true ,
} ,
{
2017-10-16 18:38:03 +03:00
desc : "stickiness=false" ,
2017-10-12 18:50:03 +03:00
tags : [ ] string {
2017-10-16 18:38:03 +03:00
types . LabelBackendLoadbalancerStickiness + "=false" ,
2017-10-12 18:50:03 +03:00
} ,
2017-10-16 18:38:03 +03:00
expected : false ,
2017-10-12 18:50:03 +03:00
} ,
}
provider := & CatalogProvider {
Prefix : "traefik" ,
}
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
actual := provider . hasStickinessLabel ( test . tags )
2017-11-13 14:14:02 +03:00
assert . Equal ( t , test . expected , actual )
} )
}
}
func TestConsulCatalogGetChangedStringKeys ( t * testing . T ) {
testCases := [ ] struct {
desc string
current [ ] string
previous [ ] string
expectedAdded [ ] string
expectedRemoved [ ] string
} {
{
desc : "1 element added, 0 removed" ,
current : [ ] string { "chou" } ,
previous : [ ] string { } ,
expectedAdded : [ ] string { "chou" } ,
expectedRemoved : [ ] string { } ,
} , {
desc : "0 element added, 0 removed" ,
current : [ ] string { "chou" } ,
previous : [ ] string { "chou" } ,
expectedAdded : [ ] string { } ,
expectedRemoved : [ ] string { } ,
} ,
{
desc : "0 element added, 1 removed" ,
current : [ ] string { } ,
previous : [ ] string { "chou" } ,
expectedAdded : [ ] string { } ,
expectedRemoved : [ ] string { "chou" } ,
} ,
{
desc : "1 element added, 1 removed" ,
current : [ ] string { "carotte" } ,
previous : [ ] string { "chou" } ,
expectedAdded : [ ] string { "carotte" } ,
expectedRemoved : [ ] string { "chou" } ,
} ,
}
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
actualAdded , actualRemoved := getChangedStringKeys ( test . current , test . previous )
assert . Equal ( t , test . expectedAdded , actualAdded )
assert . Equal ( t , test . expectedRemoved , actualRemoved )
} )
}
}
func TestConsulCatalogHasNodeOrTagschanged ( t * testing . T ) {
testCases := [ ] struct {
desc string
current map [ string ] Service
previous map [ string ] Service
expected bool
} {
{
desc : "Change detected due to change of nodes" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node2" } ,
Tags : [ ] string { } ,
} ,
} ,
expected : true ,
} ,
{
desc : "No change missing current service" ,
current : make ( map [ string ] Service ) ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
expected : false ,
} ,
{
desc : "No change on nodes" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
expected : false ,
} ,
{
desc : "No change on nodes and tags" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo=bar" } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo=bar" } ,
} ,
} ,
expected : false ,
} ,
{
2017-12-15 22:52:03 +03:00
desc : "Change detected on tags" ,
2017-11-13 14:14:02 +03:00
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo=bar" } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo" } ,
} ,
} ,
expected : true ,
} ,
2017-12-15 22:52:03 +03:00
{
desc : "Change detected on ports" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo=bar" } ,
Ports : [ ] int { 80 } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo" } ,
Ports : [ ] int { 81 } ,
} ,
} ,
expected : true ,
} ,
{
desc : "Change detected on ports" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo=bar" } ,
Ports : [ ] int { 80 } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo" } ,
Ports : [ ] int { 81 , 82 } ,
} ,
} ,
expected : true ,
} ,
{
desc : "No Change detected" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo" } ,
Ports : [ ] int { 80 } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo" } ,
Ports : [ ] int { 80 } ,
} ,
} ,
expected : false ,
} ,
2017-11-13 14:14:02 +03:00
}
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
2017-12-15 22:52:03 +03:00
actual := hasServiceChanged ( test . current , test . previous )
2017-11-13 14:14:02 +03:00
assert . Equal ( t , test . expected , actual )
} )
}
}
func TestConsulCatalogHasChanged ( t * testing . T ) {
testCases := [ ] struct {
desc string
current map [ string ] Service
previous map [ string ] Service
expected bool
} {
{
desc : "Change detected due to change new service" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
previous : make ( map [ string ] Service ) ,
expected : true ,
} ,
{
desc : "Change detected due to change service removed" ,
current : make ( map [ string ] Service ) ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
expected : true ,
} ,
{
desc : "Change detected due to change of nodes" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node2" } ,
Tags : [ ] string { } ,
} ,
} ,
expected : true ,
} ,
{
desc : "No change on nodes" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { } ,
} ,
} ,
expected : false ,
} ,
{
desc : "No change on nodes and tags" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo=bar" } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo=bar" } ,
} ,
} ,
expected : false ,
} ,
{
desc : "Change detected on tags" ,
current : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo=bar" } ,
} ,
} ,
previous : map [ string ] Service {
"foo-service" : {
Name : "foo" ,
Nodes : [ ] string { "node1" } ,
Tags : [ ] string { "foo" } ,
} ,
} ,
expected : true ,
} ,
}
for _ , test := range testCases {
test := test
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
actual := hasChanged ( test . current , test . previous )
assert . Equal ( t , test . expected , actual )
2017-10-12 18:50:03 +03:00
} )
}
}