2017-07-06 16:28:13 +02:00
package integration
2015-09-27 15:59:51 +02:00
import (
2015-11-05 15:14:25 +01:00
"encoding/json"
"fmt"
"io/ioutil"
2015-09-27 15:59:51 +02:00
"net/http"
2015-09-28 22:37:19 +02:00
"os"
2016-03-27 19:58:08 +02:00
"strings"
2015-09-27 15:59:51 +02:00
"time"
2015-11-05 15:14:25 +01:00
"github.com/docker/docker/pkg/namesgenerator"
2016-04-02 12:40:21 +02:00
"github.com/go-check/check"
2016-05-12 17:10:42 +02:00
d "github.com/libkermit/docker"
2018-02-21 16:28:03 +01:00
"github.com/libkermit/docker-check"
2020-09-16 15:46:04 +02:00
"github.com/traefik/traefik/v2/integration/try"
2015-09-27 15:59:51 +02:00
checker "github.com/vdemeester/shakers"
)
2020-05-11 12:06:07 +02:00
// Images to have or pull before the build in order to make it work.
// FIXME handle this offline but loading them before build.
2019-01-18 15:18:04 +01:00
var RequiredImages = map [ string ] string {
2020-09-16 15:46:04 +02:00
"swarm" : "1.0.0" ,
"traefik/whoami" : "latest" ,
2019-01-18 15:18:04 +01:00
}
2015-11-05 15:14:25 +01:00
2020-05-11 12:06:07 +02:00
// Docker tests suite.
2015-11-05 15:14:25 +01:00
type DockerSuite struct {
BaseSuite
2016-03-27 19:58:08 +02:00
project * docker . Project
2015-11-05 15:14:25 +01:00
}
func ( s * DockerSuite ) startContainer ( c * check . C , image string , args ... string ) string {
2016-04-02 12:40:21 +02:00
return s . startContainerWithConfig ( c , image , d . ContainerConfig {
2016-03-27 19:58:08 +02:00
Cmd : args ,
2015-11-05 15:14:25 +01:00
} )
}
func ( s * DockerSuite ) startContainerWithLabels ( c * check . C , image string , labels map [ string ] string , args ... string ) string {
2016-04-02 12:40:21 +02:00
return s . startContainerWithConfig ( c , image , d . ContainerConfig {
2016-03-27 19:58:08 +02:00
Cmd : args ,
Labels : labels ,
2015-11-05 15:14:25 +01:00
} )
}
2020-07-07 14:42:03 +02:00
func ( s * DockerSuite ) startContainerWithNameAndLabels ( c * check . C , name , image string , labels map [ string ] string , args ... string ) string {
2017-11-28 13:58:04 +01:00
return s . startContainerWithConfig ( c , image , d . ContainerConfig {
Name : name ,
Cmd : args ,
Labels : labels ,
} )
}
2016-04-02 12:40:21 +02:00
func ( s * DockerSuite ) startContainerWithConfig ( c * check . C , image string , config d . ContainerConfig ) string {
2015-11-05 15:14:25 +01:00
if config . Name == "" {
config . Name = namesgenerator . GetRandomName ( 10 )
}
2016-04-02 12:40:21 +02:00
container := s . project . StartWithConfig ( c , image , config )
2015-11-05 15:14:25 +01:00
2016-03-27 19:58:08 +02:00
// FIXME(vdemeester) this is ugly (it's because of the / in front of the name in docker..)
return strings . SplitAfter ( container . Name , "/" ) [ 1 ]
2015-11-05 15:14:25 +01:00
}
2017-11-28 13:58:04 +01:00
func ( s * DockerSuite ) stopAndRemoveContainerByName ( c * check . C , name string ) {
s . project . Stop ( c , name )
s . project . Remove ( c , name )
}
2015-11-05 15:14:25 +01:00
func ( s * DockerSuite ) SetUpSuite ( c * check . C ) {
2016-04-02 12:40:21 +02:00
project := docker . NewProjectFromEnv ( c )
2016-03-27 19:58:08 +02:00
s . project = project
2015-11-05 15:14:25 +01:00
// Pull required images
for repository , tag := range RequiredImages {
image := fmt . Sprintf ( "%s:%s" , repository , tag )
2016-04-02 12:40:21 +02:00
s . project . Pull ( c , image )
2015-11-05 15:14:25 +01:00
}
}
func ( s * DockerSuite ) TearDownTest ( c * check . C ) {
2019-01-21 19:06:02 +01:00
s . project . Clean ( c , os . Getenv ( "CIRCLECI" ) != "" ) // FIXME
2015-11-05 15:14:25 +01:00
}
2015-09-27 15:59:51 +02:00
func ( s * DockerSuite ) TestSimpleConfiguration ( c * check . C ) {
2019-01-21 19:06:02 +01:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 16:24:07 +01:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 19:06:02 +01:00
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2015-09-28 22:37:19 +02:00
defer os . Remove ( file )
2017-09-13 10:34:04 +02:00
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
2015-09-27 15:59:51 +02:00
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 09:32:03 +02:00
defer s . killCmd ( cmd )
2015-09-27 15:59:51 +02:00
// TODO validate : run on 80
2018-04-16 18:14:04 +02:00
// Expected a 404 as we did not configure anything
2017-11-20 09:40:03 +01:00
err = try . GetRequest ( "http://127.0.0.1:8000/" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusNotFound ) )
2017-05-17 15:22:44 +02:00
c . Assert ( err , checker . IsNil )
2015-11-05 15:14:25 +01:00
}
func ( s * DockerSuite ) TestDefaultDockerContainers ( c * check . C ) {
2019-01-21 19:06:02 +01:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 16:24:07 +01:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 19:06:02 +01:00
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2015-11-05 15:14:25 +01:00
defer os . Remove ( file )
2019-01-18 15:18:04 +01:00
2015-11-05 15:14:25 +01:00
name := s . startContainer ( c , "swarm:1.0.0" , "manage" , "token://blablabla" )
// Start traefik
2017-09-13 10:34:04 +02:00
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
2015-11-05 15:14:25 +01:00
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 09:32:03 +02:00
defer s . killCmd ( cmd )
2015-11-05 15:14:25 +01:00
2017-05-17 15:22:44 +02:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2015-11-05 15:14:25 +01:00
c . Assert ( err , checker . IsNil )
2020-09-15 13:08:03 +02:00
req . Host = fmt . Sprintf ( "%s.docker.localhost" , strings . ReplaceAll ( name , "_" , "-" ) )
2015-11-05 15:14:25 +01:00
2017-05-17 15:22:44 +02:00
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
2017-11-20 09:40:03 +01:00
resp , err := try . ResponseUntilStatusCode ( req , 1500 * time . Millisecond , http . StatusOK )
2015-11-05 15:14:25 +01:00
c . Assert ( err , checker . IsNil )
body , err := ioutil . ReadAll ( resp . Body )
c . Assert ( err , checker . IsNil )
2015-09-27 15:59:51 +02:00
2015-11-05 15:14:25 +01:00
var version map [ string ] interface { }
c . Assert ( json . Unmarshal ( body , & version ) , checker . IsNil )
c . Assert ( version [ "Version" ] , checker . Equals , "swarm/1.0.0" )
}
2019-03-21 15:22:06 +01:00
func ( s * DockerSuite ) TestDockerContainersWithTCPLabels ( c * check . C ) {
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
defer os . Remove ( file )
// Start a container with some labels
labels := map [ string ] string {
"traefik.tcp.Routers.Super.Rule" : "HostSNI(`my.super.host`)" ,
"traefik.tcp.Routers.Super.tls" : "true" ,
"traefik.tcp.Services.Super.Loadbalancer.server.port" : "8080" ,
}
2020-09-16 15:46:04 +02:00
s . startContainerWithLabels ( c , "traefik/whoamitcp" , labels , "-name" , "my.super.host" )
2019-03-21 15:22:06 +01:00
// Start traefik
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 09:32:03 +02:00
defer s . killCmd ( cmd )
2019-03-21 15:22:06 +01: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`)" ) )
c . Assert ( err , checker . IsNil )
who , err := guessWho ( "127.0.0.1:8000" , "my.super.host" , true )
c . Assert ( err , checker . IsNil )
c . Assert ( who , checker . Contains , "my.super.host" )
}
2015-11-05 15:14:25 +01:00
func ( s * DockerSuite ) TestDockerContainersWithLabels ( c * check . C ) {
2019-01-21 19:06:02 +01:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 16:24:07 +01:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 19:06:02 +01:00
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2015-11-05 15:14:25 +01:00
defer os . Remove ( file )
2019-01-18 15:18:04 +01:00
2015-11-05 15:14:25 +01:00
// Start a container with some labels
labels := map [ string ] string {
2019-03-14 09:30:04 +01:00
"traefik.http.Routers.Super.Rule" : "Host(`my.super.host`)" ,
2015-11-05 15:14:25 +01:00
}
s . startContainerWithLabels ( c , "swarm:1.0.0" , labels , "manage" , "token://blabla" )
2017-10-30 12:06:03 +01:00
// Start another container by replacing a '.' by a '-'
labels = map [ string ] string {
2019-03-14 09:30:04 +01:00
"traefik.http.Routers.SuperHost.Rule" : "Host(`my-super.host`)" ,
2017-10-30 12:06:03 +01:00
}
s . startContainerWithLabels ( c , "swarm:1.0.0" , labels , "manage" , "token://blablabla" )
2019-01-18 15:18:04 +01:00
2015-11-05 15:14:25 +01:00
// Start traefik
2017-09-13 10:34:04 +02:00
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
2015-11-05 15:14:25 +01:00
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 09:32:03 +02:00
defer s . killCmd ( cmd )
2015-11-05 15:14:25 +01:00
2017-05-17 15:22:44 +02:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2015-11-05 15:14:25 +01:00
c . Assert ( err , checker . IsNil )
2017-10-30 12:06:03 +01:00
req . Host = "my-super.host"
2015-11-05 15:14:25 +01:00
2017-05-17 15:22:44 +02:00
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
2017-12-02 19:26:44 +01:00
_ , err = try . ResponseUntilStatusCode ( req , 1500 * time . Millisecond , http . StatusOK )
2015-11-05 15:14:25 +01:00
c . Assert ( err , checker . IsNil )
2017-10-30 12:06:03 +01:00
req , err = http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "my.super.host"
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
2017-12-02 19:26:44 +01:00
resp , err := try . ResponseUntilStatusCode ( req , 1500 * time . Millisecond , http . StatusOK )
2017-10-30 12:06:03 +01:00
c . Assert ( err , checker . IsNil )
2015-11-05 15:14:25 +01:00
body , err := ioutil . ReadAll ( resp . Body )
c . Assert ( err , checker . IsNil )
var version map [ string ] interface { }
c . Assert ( json . Unmarshal ( body , & version ) , checker . IsNil )
c . Assert ( version [ "Version" ] , checker . Equals , "swarm/1.0.0" )
}
func ( s * DockerSuite ) TestDockerContainersWithOneMissingLabels ( c * check . C ) {
2019-01-21 19:06:02 +01:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 16:24:07 +01:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 19:06:02 +01:00
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2015-11-05 15:14:25 +01:00
defer os . Remove ( file )
2019-01-18 15:18:04 +01:00
2015-11-05 15:14:25 +01:00
// Start a container with some labels
labels := map [ string ] string {
2019-01-18 15:18:04 +01:00
"traefik.random.value" : "my.super.host" ,
2015-11-05 15:14:25 +01:00
}
s . startContainerWithLabels ( c , "swarm:1.0.0" , labels , "manage" , "token://blabla" )
// Start traefik
2017-09-13 10:34:04 +02:00
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
2015-11-05 15:14:25 +01:00
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 09:32:03 +02:00
defer s . killCmd ( cmd )
2015-11-05 15:14:25 +01:00
2017-05-17 15:22:44 +02:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2015-11-05 15:14:25 +01:00
c . Assert ( err , checker . IsNil )
2017-05-17 15:22:44 +02:00
req . Host = "my.super.host"
2015-11-05 15:14:25 +01:00
2017-05-17 15:22:44 +02:00
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
// TODO validate : run on 80
2019-01-21 19:06:02 +01:00
// Expected a 404 as we did not configure anything
2017-05-17 15:22:44 +02:00
err = try . Request ( req , 1500 * time . Millisecond , try . StatusCodeIs ( http . StatusNotFound ) )
2015-11-05 15:14:25 +01:00
c . Assert ( err , checker . IsNil )
2015-09-27 15:59:51 +02:00
}
2017-10-30 15:10:05 +01:00
2017-11-28 13:58:04 +01:00
func ( s * DockerSuite ) TestRestartDockerContainers ( c * check . C ) {
2019-01-21 19:06:02 +01:00
tempObjects := struct {
DockerHost string
DefaultRule string
} {
DockerHost : s . getDockerHost ( ) ,
2019-01-30 16:24:07 +01:00
DefaultRule : "Host(`{{ normalize .Name }}.docker.localhost`)" ,
2019-01-21 19:06:02 +01:00
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2017-11-28 13:58:04 +01:00
defer os . Remove ( file )
2019-01-18 15:18:04 +01:00
2017-11-28 13:58:04 +01:00
// Start a container with some labels
labels := map [ string ] string {
2019-03-14 09:30:04 +01:00
"traefik.http.Routers.Super.Rule" : "Host(`my.super.host`)" ,
"traefik.http.Services.powpow.LoadBalancer.server.Port" : "2375" ,
2017-11-28 13:58:04 +01:00
}
s . startContainerWithNameAndLabels ( c , "powpow" , "swarm:1.0.0" , labels , "manage" , "token://blabla" )
// Start traefik
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 09:32:03 +02:00
defer s . killCmd ( cmd )
2017-11-28 13:58:04 +01:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "my.super.host"
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
resp , err := try . ResponseUntilStatusCode ( req , 1500 * time . Millisecond , http . StatusOK )
c . Assert ( err , checker . IsNil )
body , err := ioutil . ReadAll ( resp . Body )
c . Assert ( err , checker . IsNil )
var version map [ string ] interface { }
c . Assert ( json . Unmarshal ( body , & version ) , checker . IsNil )
c . Assert ( version [ "Version" ] , checker . Equals , "swarm/1.0.0" )
2019-05-16 10:58:06 +02:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 60 * time . Second , try . BodyContains ( "powpow" ) )
2017-11-28 13:58:04 +01:00
c . Assert ( err , checker . IsNil )
s . stopAndRemoveContainerByName ( c , "powpow" )
defer s . project . Remove ( c , "powpow" )
time . Sleep ( 5 * time . Second )
2019-05-16 10:58:06 +02:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 10 * time . Second , try . BodyContains ( "powpow" ) )
2017-11-28 13:58:04 +01:00
c . Assert ( err , checker . NotNil )
s . startContainerWithNameAndLabels ( c , "powpow" , "swarm:1.0.0" , labels , "manage" , "token://blabla" )
2019-05-16 10:58:06 +02:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 60 * time . Second , try . BodyContains ( "powpow" ) )
2017-11-28 13:58:04 +01:00
c . Assert ( err , checker . IsNil )
}