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"
"fmt"
2021-03-04 22:08:03 +03:00
"io"
2015-09-27 16:59:51 +03:00
"net/http"
2015-09-28 23:37:19 +03:00
"os"
2016-03-27 20:58:08 +03:00
"strings"
2015-09-27 16:59:51 +03:00
"time"
2015-11-05 17:14:25 +03:00
"github.com/docker/docker/pkg/namesgenerator"
2016-04-02 13:40:21 +03:00
"github.com/go-check/check"
2016-05-12 18:10:42 +03:00
d "github.com/libkermit/docker"
2018-02-21 18:28:03 +03:00
"github.com/libkermit/docker-check"
2020-09-16 16:46:04 +03:00
"github.com/traefik/traefik/v2/integration/try"
2015-09-27 16:59:51 +03:00
checker "github.com/vdemeester/shakers"
)
2020-05-11 13:06:07 +03: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 17:18:04 +03:00
var RequiredImages = map [ string ] string {
2020-09-16 16:46:04 +03:00
"swarm" : "1.0.0" ,
"traefik/whoami" : "latest" ,
2019-01-18 17:18:04 +03:00
}
2015-11-05 17:14:25 +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
2016-03-27 20:58:08 +03:00
project * docker . Project
2015-11-05 17:14:25 +03:00
}
func ( s * DockerSuite ) startContainer ( c * check . C , image string , args ... string ) string {
2016-04-02 13:40:21 +03:00
return s . startContainerWithConfig ( c , image , d . ContainerConfig {
2016-03-27 20:58:08 +03:00
Cmd : args ,
2015-11-05 17:14:25 +03:00
} )
}
func ( s * DockerSuite ) startContainerWithLabels ( c * check . C , image string , labels map [ string ] string , args ... string ) string {
2016-04-02 13:40:21 +03:00
return s . startContainerWithConfig ( c , image , d . ContainerConfig {
2016-03-27 20:58:08 +03:00
Cmd : args ,
Labels : labels ,
2015-11-05 17:14:25 +03:00
} )
}
2020-07-07 15:42:03 +03:00
func ( s * DockerSuite ) startContainerWithNameAndLabels ( c * check . C , name , image string , labels map [ string ] string , args ... string ) string {
2017-11-28 15:58:04 +03:00
return s . startContainerWithConfig ( c , image , d . ContainerConfig {
Name : name ,
Cmd : args ,
Labels : labels ,
} )
}
2016-04-02 13:40:21 +03:00
func ( s * DockerSuite ) startContainerWithConfig ( c * check . C , image string , config d . ContainerConfig ) string {
2015-11-05 17:14:25 +03:00
if config . Name == "" {
config . Name = namesgenerator . GetRandomName ( 10 )
}
2016-04-02 13:40:21 +03:00
container := s . project . StartWithConfig ( c , image , config )
2015-11-05 17:14:25 +03:00
2016-03-27 20:58:08 +03: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 17:14:25 +03:00
}
2017-11-28 15:58:04 +03:00
func ( s * DockerSuite ) stopAndRemoveContainerByName ( c * check . C , name string ) {
s . project . Stop ( c , name )
s . project . Remove ( c , name )
}
2015-11-05 17:14:25 +03:00
func ( s * DockerSuite ) SetUpSuite ( c * check . C ) {
2016-04-02 13:40:21 +03:00
project := docker . NewProjectFromEnv ( c )
2016-03-27 20:58:08 +03:00
s . project = project
2015-11-05 17:14:25 +03:00
// Pull required images
for repository , tag := range RequiredImages {
image := fmt . Sprintf ( "%s:%s" , repository , tag )
2016-04-02 13:40:21 +03:00
s . project . Pull ( c , image )
2015-11-05 17:14:25 +03:00
}
}
func ( s * DockerSuite ) TearDownTest ( c * check . C ) {
2019-01-21 21:06:02 +03:00
s . project . Clean ( c , os . Getenv ( "CIRCLECI" ) != "" ) // FIXME
2015-11-05 17:14:25 +03:00
}
2015-09-27 16:59:51 +03:00
func ( s * DockerSuite ) TestSimpleConfiguration ( c * check . C ) {
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
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2015-09-28 23:37:19 +03:00
defer os . Remove ( file )
2017-09-13 11:34:04 +03:00
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
2015-09-27 16:59:51 +03:00
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2015-09-27 16:59:51 +03:00
// TODO validate : run on 80
2018-04-16 19:14:04 +03:00
// Expected a 404 as we did not configure anything
2017-11-20 11:40:03 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/" , 500 * time . Millisecond , try . StatusCodeIs ( http . StatusNotFound ) )
2017-05-17 16:22:44 +03:00
c . Assert ( err , checker . IsNil )
2015-11-05 17:14:25 +03:00
}
func ( s * DockerSuite ) TestDefaultDockerContainers ( c * check . C ) {
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
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2015-11-05 17:14:25 +03:00
defer os . Remove ( file )
2019-01-18 17:18:04 +03:00
2015-11-05 17:14:25 +03:00
name := s . startContainer ( c , "swarm:1.0.0" , "manage" , "token://blablabla" )
// Start traefik
2017-09-13 11:34:04 +03:00
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
2015-11-05 17:14:25 +03:00
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
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 )
2015-11-05 17:14:25 +03:00
c . Assert ( err , checker . IsNil )
2020-09-15 14:08:03 +03:00
req . Host = fmt . Sprintf ( "%s.docker.localhost" , strings . ReplaceAll ( name , "_" , "-" ) )
2015-11-05 17:14:25 +03:00
2017-05-17 16:22:44 +03:00
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
2017-11-20 11:40:03 +03:00
resp , err := try . ResponseUntilStatusCode ( req , 1500 * time . Millisecond , http . StatusOK )
2015-11-05 17:14:25 +03:00
c . Assert ( err , checker . IsNil )
2021-03-04 22:08:03 +03:00
body , err := io . ReadAll ( resp . Body )
2015-11-05 17:14:25 +03:00
c . Assert ( err , checker . IsNil )
2015-09-27 16:59:51 +03:00
2015-11-05 17:14:25 +03: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 17:22:06 +03: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 16:46:04 +03:00
s . startContainerWithLabels ( c , "traefik/whoamitcp" , labels , "-name" , "my.super.host" )
2019-03-21 17:22:06 +03:00
// Start traefik
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-03-21 17:22:06 +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`)" ) )
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 17:14:25 +03:00
func ( s * DockerSuite ) TestDockerContainersWithLabels ( c * check . C ) {
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
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2015-11-05 17:14:25 +03:00
defer os . Remove ( file )
2019-01-18 17:18:04 +03:00
2015-11-05 17:14:25 +03:00
// Start a container with some labels
labels := map [ string ] string {
2019-03-14 11:30:04 +03:00
"traefik.http.Routers.Super.Rule" : "Host(`my.super.host`)" ,
2015-11-05 17:14:25 +03:00
}
s . startContainerWithLabels ( c , "swarm:1.0.0" , labels , "manage" , "token://blabla" )
2017-10-30 14:06:03 +03:00
// Start another container by replacing a '.' by a '-'
labels = map [ string ] string {
2019-03-14 11:30:04 +03:00
"traefik.http.Routers.SuperHost.Rule" : "Host(`my-super.host`)" ,
2017-10-30 14:06:03 +03:00
}
s . startContainerWithLabels ( c , "swarm:1.0.0" , labels , "manage" , "token://blablabla" )
2019-01-18 17:18:04 +03:00
2015-11-05 17:14:25 +03:00
// Start traefik
2017-09-13 11:34:04 +03:00
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
2015-11-05 17:14:25 +03:00
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
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 )
2015-11-05 17:14:25 +03:00
c . Assert ( err , checker . IsNil )
2017-10-30 14:06:03 +03:00
req . Host = "my-super.host"
2015-11-05 17:14:25 +03:00
2017-05-17 16:22:44 +03:00
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
2017-12-02 21:26:44 +03:00
_ , err = try . ResponseUntilStatusCode ( req , 1500 * time . Millisecond , http . StatusOK )
2015-11-05 17:14:25 +03:00
c . Assert ( err , checker . IsNil )
2017-10-30 14:06:03 +03: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 21:26:44 +03:00
resp , err := try . ResponseUntilStatusCode ( req , 1500 * time . Millisecond , http . StatusOK )
2017-10-30 14:06:03 +03:00
c . Assert ( err , checker . IsNil )
2021-03-04 22:08:03 +03:00
body , err := io . ReadAll ( resp . Body )
2015-11-05 17:14:25 +03:00
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 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
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2015-11-05 17:14:25 +03:00
defer os . Remove ( file )
2019-01-18 17:18:04 +03:00
2015-11-05 17:14:25 +03:00
// Start a container with some labels
labels := map [ string ] string {
2019-01-18 17:18:04 +03:00
"traefik.random.value" : "my.super.host" ,
2015-11-05 17:14:25 +03:00
}
s . startContainerWithLabels ( c , "swarm:1.0.0" , labels , "manage" , "token://blabla" )
// Start traefik
2017-09-13 11:34:04 +03:00
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
2015-11-05 17:14:25 +03:00
err := cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
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 )
2015-11-05 17:14:25 +03:00
c . Assert ( err , checker . IsNil )
2017-05-17 16:22:44 +03:00
req . Host = "my.super.host"
2015-11-05 17:14:25 +03:00
2017-05-17 16:22:44 +03:00
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
// TODO validate : run on 80
2019-01-21 21:06:02 +03:00
// Expected a 404 as we did not configure anything
2017-05-17 16:22:44 +03:00
err = try . Request ( req , 1500 * time . Millisecond , try . StatusCodeIs ( http . StatusNotFound ) )
2015-11-05 17:14:25 +03:00
c . Assert ( err , checker . IsNil )
2015-09-27 16:59:51 +03:00
}
2017-10-30 17:10:05 +03:00
2017-11-28 15:58:04 +03:00
func ( s * DockerSuite ) TestRestartDockerContainers ( c * check . C ) {
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
}
file := s . adaptFile ( c , "fixtures/docker/simple.toml" , tempObjects )
2017-11-28 15:58:04 +03:00
defer os . Remove ( file )
2019-01-18 17:18:04 +03:00
2017-11-28 15:58:04 +03:00
// Start a container with some labels
labels := map [ string ] string {
2019-03-14 11:30:04 +03:00
"traefik.http.Routers.Super.Rule" : "Host(`my.super.host`)" ,
"traefik.http.Services.powpow.LoadBalancer.server.Port" : "2375" ,
2017-11-28 15:58:04 +03: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 10:32:03 +03:00
defer s . killCmd ( cmd )
2017-11-28 15:58:04 +03: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 )
2021-03-04 22:08:03 +03:00
body , err := io . ReadAll ( resp . Body )
2017-11-28 15:58:04 +03:00
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 11:58:06 +03:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 60 * time . Second , try . BodyContains ( "powpow" ) )
2017-11-28 15:58:04 +03:00
c . Assert ( err , checker . IsNil )
s . stopAndRemoveContainerByName ( c , "powpow" )
defer s . project . Remove ( c , "powpow" )
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" ) )
2017-11-28 15:58:04 +03:00
c . Assert ( err , checker . NotNil )
s . startContainerWithNameAndLabels ( c , "powpow" , "swarm:1.0.0" , labels , "manage" , "token://blabla" )
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" ) )
2017-11-28 15:58:04 +03:00
c . Assert ( err , checker . IsNil )
}