2017-07-06 17:28:13 +03:00
package integration
2015-09-27 16:59:51 +03:00
import (
2015-11-05 17:14:25 +03:00
"encoding/json"
2021-03-04 22:08:03 +03:00
"io"
2015-09-27 16:59:51 +03:00
"net/http"
2024-01-26 03:44:05 +03:00
"strings"
2024-01-09 19:00:07 +03:00
"testing"
2015-09-27 16:59:51 +03:00
"time"
2024-01-09 19:00:07 +03:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
2023-02-03 17:24:05 +03:00
"github.com/traefik/traefik/v3/integration/try"
2015-09-27 16:59:51 +03:00
)
2020-05-11 13:06:07 +03:00
// Docker tests suite.
2015-11-05 17:14:25 +03:00
type DockerSuite struct {
BaseSuite
2017-11-28 15:58:04 +03:00
}
2024-01-09 19:00:07 +03:00
func TestDockerSuite ( t * testing . T ) {
suite . Run ( t , new ( DockerSuite ) )
2015-11-05 17:14:25 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * DockerSuite ) SetupSuite ( ) {
s . BaseSuite . SetupSuite ( )
s . createComposeProject ( "docker" )
2015-11-05 17:14:25 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * DockerSuite ) TearDownSuite ( ) {
s . BaseSuite . TearDownSuite ( )
}
func ( s * DockerSuite ) TearDownTest ( ) {
s . composeStop ( "simple" , "withtcplabels" , "withlabels1" , "withlabels2" , "withonelabelmissing" , "powpow" )
}
func ( s * DockerSuite ) TestSimpleConfiguration ( ) {
2019-01-21 21:06:02 +03:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 18:24:07 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 21:06:02 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/docker/simple.toml" , tempObjects )
2015-09-28 23:37:19 +03:00
2024-01-09 19:00:07 +03:00
s . composeUp ( )
2021-11-25 13:10:06 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2015-09-27 16:59:51 +03:00
2018-04-16 19:14:04 +03:00
// Expected a 404 as we did not configure anything
2024-01-09 19:00:07 +03:00
err := try . GetRequest ( "http://127.0.0.1:8000/" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusNotFound ) )
require . NoError ( s . T ( ) , err )
2015-11-05 17:14:25 +03:00
}
2024-01-26 03:44:05 +03:00
func ( s * DockerSuite ) TestWRRServer ( ) {
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
}
file := s . adaptFile ( "fixtures/docker/simple.toml" , tempObjects )
s . composeUp ( )
s . traefikCmd ( withConfigFile ( file ) )
whoami1IP := s . getComposeServiceIP ( "wrr-server" )
whoami2IP := s . getComposeServiceIP ( "wrr-server2" )
// Expected a 404 as we did not configure anything
err := try . GetRequest ( "http://127.0.0.1:8000/" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusNotFound ) )
require . NoError ( s . T ( ) , err )
err = try . GetRequest ( "http://127.0.0.1:8080/api/http/services" , 1000 * time . Millisecond , try . BodyContains ( "wrr-server" ) )
require . NoError ( s . T ( ) , err )
repartition := map [ string ] int { }
2024-06-05 00:58:38 +03:00
for range 4 {
2024-01-26 03:44:05 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/whoami" , nil )
req . Host = "my.wrr.host"
require . NoError ( s . T ( ) , err )
response , err := http . DefaultClient . Do ( req )
require . NoError ( s . T ( ) , err )
assert . Equal ( s . T ( ) , http . StatusOK , response . StatusCode )
body , err := io . ReadAll ( response . Body )
require . NoError ( s . T ( ) , err )
if strings . Contains ( string ( body ) , whoami1IP ) {
repartition [ whoami1IP ] ++
}
if strings . Contains ( string ( body ) , whoami2IP ) {
repartition [ whoami2IP ] ++
}
}
assert . Equal ( s . T ( ) , 3 , repartition [ whoami1IP ] )
assert . Equal ( s . T ( ) , 1 , repartition [ whoami2IP ] )
}
2024-01-09 19:00:07 +03:00
func ( s * DockerSuite ) TestDefaultDockerContainers ( ) {
2019-01-21 21:06:02 +03:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 18:24:07 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 21:06:02 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/docker/simple.toml" , tempObjects )
2019-01-18 17:18:04 +03:00
2024-01-09 19:00:07 +03:00
s . composeUp ( "simple" )
2015-11-05 17:14:25 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2015-11-05 17:14:25 +03:00
2017-05-17 16:22:44 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
req . Host = "simple.docker.localhost"
2015-11-05 17:14:25 +03:00
2024-01-09 19:00:07 +03:00
resp , err := try . ResponseUntilStatusCode ( req , 3 * time . Second , http . StatusOK )
require . NoError ( s . T ( ) , err )
2015-11-05 17:14:25 +03:00
2021-03-04 22:08:03 +03:00
body , err := io . ReadAll ( resp . Body )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2015-09-27 16:59:51 +03:00
2015-11-05 17:14:25 +03:00
var version map [ string ] interface { }
2024-01-09 19:00:07 +03:00
assert . NoError ( s . T ( ) , json . Unmarshal ( body , & version ) )
assert . Equal ( s . T ( ) , "swarm/1.0.0" , version [ "Version" ] )
2015-11-05 17:14:25 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * DockerSuite ) TestDockerContainersWithTCPLabels ( ) {
2019-03-21 17:22:06 +03:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/docker/simple.toml" , tempObjects )
2019-03-21 17:22:06 +03:00
2024-01-09 19:00:07 +03:00
s . composeUp ( "withtcplabels" )
2019-03-21 17:22:06 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2021-11-25 13:10:06 +03:00
2024-01-09 19:00:07 +03:00
err := try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) , try . BodyContains ( "HostSNI(`my.super.host`)" ) )
require . NoError ( s . T ( ) , err )
2019-03-21 17:22:06 +03:00
who , err := guessWho ( "127.0.0.1:8000" , "my.super.host" , true )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-03-21 17:22:06 +03:00
2024-01-09 19:00:07 +03:00
assert . Contains ( s . T ( ) , who , "my.super.host" )
2019-03-21 17:22:06 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * DockerSuite ) TestDockerContainersWithLabels ( ) {
2019-01-21 21:06:02 +03:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 18:24:07 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 21:06:02 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/docker/simple.toml" , tempObjects )
2019-01-18 17:18:04 +03:00
2024-01-09 19:00:07 +03:00
s . composeUp ( "withlabels1" , "withlabels2" )
2019-01-18 17:18:04 +03:00
2015-11-05 17:14:25 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2015-11-05 17:14:25 +03:00
2017-05-17 16:22:44 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-10-30 14:06:03 +03:00
req . Host = "my-super.host"
2015-11-05 17:14:25 +03:00
2024-01-09 19:00:07 +03:00
_ , err = try . ResponseUntilStatusCode ( req , 3 * time . Second , http . StatusOK )
require . NoError ( s . T ( ) , err )
2015-11-05 17:14:25 +03:00
2017-10-30 14:06:03 +03:00
req , err = http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-10-30 14:06:03 +03:00
req . Host = "my.super.host"
2024-01-09 19:00:07 +03:00
resp , err := try . ResponseUntilStatusCode ( req , 3 * time . Second , http . StatusOK )
require . NoError ( s . T ( ) , err )
2017-10-30 14:06:03 +03:00
2021-03-04 22:08:03 +03:00
body , err := io . ReadAll ( resp . Body )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2015-11-05 17:14:25 +03:00
var version map [ string ] interface { }
2024-01-09 19:00:07 +03:00
assert . NoError ( s . T ( ) , json . Unmarshal ( body , & version ) )
assert . Equal ( s . T ( ) , "swarm/1.0.0" , version [ "Version" ] )
2015-11-05 17:14:25 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * DockerSuite ) TestDockerContainersWithOneMissingLabels ( ) {
2019-01-21 21:06:02 +03:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 18:24:07 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 21:06:02 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/docker/simple.toml" , tempObjects )
2019-01-18 17:18:04 +03:00
2024-01-09 19:00:07 +03:00
s . composeUp ( "withonelabelmissing" )
2015-11-05 17:14:25 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2015-11-05 17:14:25 +03:00
2017-05-17 16:22:44 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-05-17 16:22:44 +03:00
req . Host = "my.super.host"
2015-11-05 17:14:25 +03:00
2019-01-21 21:06:02 +03:00
// Expected a 404 as we did not configure anything
2024-01-09 19:00:07 +03:00
err = try . Request ( req , 3 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
require . NoError ( s . T ( ) , err )
2015-09-27 16:59:51 +03:00
}
2017-10-30 17:10:05 +03:00
2024-01-09 19:00:07 +03:00
func ( s * DockerSuite ) TestRestartDockerContainers ( ) {
2019-01-21 21:06:02 +03:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 18:24:07 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 21:06:02 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/docker/simple.toml" , tempObjects )
2019-01-18 17:18:04 +03:00
2024-01-09 19:00:07 +03:00
s . composeUp ( "powpow" )
2017-11-28 15:58:04 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2017-11-28 15:58:04 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-11-28 15:58:04 +03:00
req . Host = "my.super.host"
2022-08-31 09:24:08 +03:00
// TODO Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
2017-11-28 15:58:04 +03:00
resp , err := try . ResponseUntilStatusCode ( req , 1500 * time . Millisecond , http . StatusOK )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-11-28 15:58:04 +03:00
2021-03-04 22:08:03 +03:00
body , err := io . ReadAll ( resp . Body )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-11-28 15:58:04 +03:00
var version map [ string ] interface { }
2024-01-09 19:00:07 +03:00
assert . NoError ( s . T ( ) , json . Unmarshal ( body , & version ) )
assert . Equal ( s . T ( ) , "swarm/1.0.0" , version [ "Version" ] )
2017-11-28 15:58:04 +03:00
2019-05-16 11:58:06 +03:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 60 * time . Second , try . BodyContains ( "powpow" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-11-28 15:58:04 +03:00
2024-01-09 19:00:07 +03:00
s . composeStop ( "powpow" )
2017-11-28 15:58:04 +03:00
time . Sleep ( 5 * time . Second )
2019-05-16 11:58:06 +03:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 10 * time . Second , try . BodyContains ( "powpow" ) )
2024-01-09 19:00:07 +03:00
assert . Error ( s . T ( ) , err )
2017-11-28 15:58:04 +03:00
2024-01-09 19:00:07 +03:00
s . composeUp ( "powpow" )
2019-05-16 11:58:06 +03:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 60 * time . Second , try . BodyContains ( "powpow" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2017-11-28 15:58:04 +03:00
}