Add initial test-integration suites
Uses go-check in order to separate integration tests into suites, and have Setup and TearDown operations (on Suites and Tests) ; and use libcompose to start the external dependencies to test on (like consul, marathon, etcd, some http images, etc..). - Update Godeps to get dependencies needed for the use of libcompose - Setup initial suites and go-check + libcompose mini-framework - Add some hacks related to libcompose, will be fixed later (when fixed upstream) Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
a5a8d6929e
commit
ad60b301b7
17 changed files with 681 additions and 0 deletions
51
integration/basic_test.go
Normal file
51
integration/basic_test.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
checker "github.com/vdemeester/shakers"
|
||||
check "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *SimpleSuite) TestNoOrInexistentConfigShouldFail(c *check.C) {
|
||||
cmd := exec.Command(traefikBinary)
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(string(output), checker.Contains, "Error reading file open traefik.toml: no such file or directory")
|
||||
|
||||
nonExistentFile := "non/existent/file.toml"
|
||||
cmd = exec.Command(traefikBinary, nonExistentFile)
|
||||
output, err = cmd.CombinedOutput()
|
||||
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(string(output), checker.Contains, fmt.Sprintf("Error reading file open %s: no such file or directory", nonExistentFile))
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestInvalidConfigShouldFail(c *check.C) {
|
||||
cmd := exec.Command(traefikBinary, "fixtures/invalid_configuration.toml")
|
||||
output, err := cmd.CombinedOutput()
|
||||
|
||||
c.Assert(err, checker.NotNil)
|
||||
c.Assert(string(output), checker.Contains, "Error reading file Near line 1")
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestSimpleDefaultConfig(c *check.C) {
|
||||
cmd := exec.Command(traefikBinary, "fixtures/simple_default.toml")
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// TODO validate : run on 80
|
||||
resp, err := http.Get("http://127.0.0.1/")
|
||||
|
||||
// Expected a 404 as we did not comfigure anything
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(resp.StatusCode, checker.Equals, 404)
|
||||
|
||||
killErr := cmd.Process.Kill()
|
||||
c.Assert(killErr, checker.IsNil)
|
||||
}
|
27
integration/consul_test.go
Normal file
27
integration/consul_test.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
checker "github.com/vdemeester/shakers"
|
||||
check "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *ConsulSuite) TestSimpleConfiguration(c *check.C) {
|
||||
cmd := exec.Command(traefikBinary, "fixtures/consul/simple.toml")
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// TODO validate : run on 80
|
||||
resp, err := http.Get("http://127.0.0.1/")
|
||||
|
||||
// Expected a 404 as we did not comfigure anything
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(resp.StatusCode, checker.Equals, 404)
|
||||
|
||||
killErr := cmd.Process.Kill()
|
||||
c.Assert(killErr, checker.IsNil)
|
||||
}
|
27
integration/docker_test.go
Normal file
27
integration/docker_test.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
checker "github.com/vdemeester/shakers"
|
||||
check "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *DockerSuite) TestSimpleConfiguration(c *check.C) {
|
||||
cmd := exec.Command(traefikBinary, "fixtures/docker/simple.toml")
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// TODO validate : run on 80
|
||||
resp, err := http.Get("http://127.0.0.1/")
|
||||
|
||||
// Expected a 404 as we did not comfigure anything
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(resp.StatusCode, checker.Equals, 404)
|
||||
|
||||
killErr := cmd.Process.Kill()
|
||||
c.Assert(killErr, checker.IsNil)
|
||||
}
|
27
integration/file_test.go
Normal file
27
integration/file_test.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
checker "github.com/vdemeester/shakers"
|
||||
check "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *FileSuite) TestSimpleConfiguration(c *check.C) {
|
||||
cmd := exec.Command(traefikBinary, "fixtures/file/simple.toml")
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// TODO validate : run on 80
|
||||
resp, err := http.Get("http://127.0.0.1/")
|
||||
|
||||
// Expected a 404 as we did not comfigure anything
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(resp.StatusCode, checker.Equals, 404)
|
||||
|
||||
killErr := cmd.Process.Kill()
|
||||
c.Assert(killErr, checker.IsNil)
|
||||
}
|
11
integration/fixtures/consul/simple.toml
Normal file
11
integration/fixtures/consul/simple.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Reverse proxy port
|
||||
#
|
||||
# Optional
|
||||
# Default: ":80"
|
||||
#
|
||||
# port = ":80"
|
||||
#
|
||||
# LogLevel
|
||||
logLevel = "DEBUG"
|
||||
|
||||
[consul]
|
16
integration/fixtures/docker/simple.toml
Normal file
16
integration/fixtures/docker/simple.toml
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Reverse proxy port
|
||||
#
|
||||
# Optional
|
||||
# Default: ":80"
|
||||
#
|
||||
# port = ":80"
|
||||
#
|
||||
# LogLevel
|
||||
logLevel = "DEBUG"
|
||||
|
||||
[docker]
|
||||
|
||||
# FIXME this should be "dynamic".. xD
|
||||
endpoint = "tcp://172.17.42.1:2375"
|
||||
|
||||
domain = "docker.localhost"
|
11
integration/fixtures/file/simple.toml
Normal file
11
integration/fixtures/file/simple.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Reverse proxy port
|
||||
#
|
||||
# Optional
|
||||
# Default: ":80"
|
||||
#
|
||||
# port = ":80"
|
||||
#
|
||||
# LogLevel
|
||||
logLevel = "DEBUG"
|
||||
|
||||
[file]
|
3
integration/fixtures/invalid_configuration.toml
Normal file
3
integration/fixtures/invalid_configuration.toml
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"who": ["am", "I", "?", "JSON"]
|
||||
}
|
11
integration/fixtures/marathon/simple.toml
Normal file
11
integration/fixtures/marathon/simple.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Reverse proxy port
|
||||
#
|
||||
# Optional
|
||||
# Default: ":80"
|
||||
#
|
||||
# port = ":80"
|
||||
#
|
||||
# LogLevel
|
||||
logLevel = "DEBUG"
|
||||
|
||||
[marathon]
|
9
integration/fixtures/simple_default.toml
Normal file
9
integration/fixtures/simple_default.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Reverse proxy port
|
||||
#
|
||||
# Optional
|
||||
# Default: ":80"
|
||||
#
|
||||
# port = ":80"
|
||||
#
|
||||
# LogLevel
|
||||
logLevel = "DEBUG"
|
130
integration/integration_test.go
Normal file
130
integration/integration_test.go
Normal file
|
@ -0,0 +1,130 @@
|
|||
// This is the main file that sets up integration tests using go-check.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
// "os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/libcompose/docker"
|
||||
"github.com/docker/libcompose/project"
|
||||
|
||||
checker "github.com/vdemeester/shakers"
|
||||
check "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
check.TestingT(t)
|
||||
}
|
||||
|
||||
func init() {
|
||||
check.Suite(&SimpleSuite{})
|
||||
check.Suite(&FileSuite{})
|
||||
check.Suite(&DockerSuite{})
|
||||
check.Suite(&ConsulSuite{})
|
||||
check.Suite(&MarathonSuite{})
|
||||
}
|
||||
|
||||
var traefikBinary = "../dist/traefik"
|
||||
|
||||
// SimpleSuite
|
||||
type SimpleSuite struct{ BaseSuite }
|
||||
|
||||
// File test suites
|
||||
type FileSuite struct{ BaseSuite }
|
||||
|
||||
func (s *FileSuite) SetUpSuite(c *check.C) {
|
||||
s.createComposeProject(c, "file")
|
||||
|
||||
s.composeProject.Up()
|
||||
}
|
||||
|
||||
// Docker test suites
|
||||
type DockerSuite struct{ BaseSuite }
|
||||
|
||||
func (s *DockerSuite) SetUpSuite(c *check.C) {
|
||||
// Make sure we can speak to docker
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TearDownSuite(c *check.C) {
|
||||
// Clean the mess
|
||||
}
|
||||
|
||||
// Consul test suites (using libcompose)
|
||||
type ConsulSuite struct{ BaseSuite }
|
||||
|
||||
func (s *ConsulSuite) SetUpSuite(c *check.C) {
|
||||
s.createComposeProject(c, "consul")
|
||||
}
|
||||
|
||||
// Marathon test suites (using libcompose)
|
||||
type MarathonSuite struct{ BaseSuite }
|
||||
|
||||
func (s *MarathonSuite) SetUpSuite(c *check.C) {
|
||||
s.createComposeProject(c, "marathon")
|
||||
}
|
||||
|
||||
type BaseSuite struct {
|
||||
composeProject *project.Project
|
||||
listenChan chan project.ProjectEvent
|
||||
started chan bool
|
||||
stopped chan bool
|
||||
deleted chan bool
|
||||
}
|
||||
|
||||
func (s *BaseSuite) TearDownSuite(c *check.C) {
|
||||
// shutdown and delete compose project
|
||||
if s.composeProject != nil {
|
||||
s.composeProject.Down()
|
||||
// Waiting for libcompose#55 to be merged
|
||||
// <-s.stopped
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
s.composeProject.Delete()
|
||||
// Waiting for libcompose#55 to be merged
|
||||
// <-s.deleted
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BaseSuite) createComposeProject(c *check.C, name string) {
|
||||
composeProject, err := docker.NewProject(&docker.Context{
|
||||
Context: project.Context{
|
||||
ComposeFile: fmt.Sprintf("resources/compose/%s.yml", name),
|
||||
ProjectName: fmt.Sprintf("integration-test-%s", name),
|
||||
},
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
s.composeProject = composeProject
|
||||
|
||||
s.listenChan = make(chan project.ProjectEvent)
|
||||
go s.startListening(c)
|
||||
|
||||
composeProject.AddListener(s.listenChan)
|
||||
|
||||
composeProject.Start()
|
||||
|
||||
// FIXME Wait for compose to start
|
||||
// Waiting for libcompose#55 to be merged
|
||||
// <-s.started
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
}
|
||||
|
||||
func (s *BaseSuite) startListening(c *check.C) {
|
||||
for event := range s.listenChan {
|
||||
// FIXME Remove this when it's working (libcompose#55)
|
||||
// fmt.Fprintf(os.Stdout, "Event: %s (%v)\n", event.Event, event)
|
||||
// FIXME Add a timeout on event
|
||||
if event.Event == project.PROJECT_UP_DONE {
|
||||
s.started <- true
|
||||
}
|
||||
if event.Event == project.PROJECT_DOWN_DONE {
|
||||
s.stopped <- true
|
||||
}
|
||||
if event.Event == project.PROJECT_DELETE_DONE {
|
||||
s.deleted <- true
|
||||
}
|
||||
}
|
||||
}
|
27
integration/marathon_test.go
Normal file
27
integration/marathon_test.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
checker "github.com/vdemeester/shakers"
|
||||
check "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *MarathonSuite) TestSimpleConfiguration(c *check.C) {
|
||||
cmd := exec.Command(traefikBinary, "fixtures/consul/simple.toml")
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// TODO validate : run on 80
|
||||
resp, err := http.Get("http://127.0.0.1/")
|
||||
|
||||
// Expected a 404 as we did not comfigure anything
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(resp.StatusCode, checker.Equals, 404)
|
||||
|
||||
killErr := cmd.Process.Kill()
|
||||
c.Assert(killErr, checker.IsNil)
|
||||
}
|
21
integration/resources/compose/consul.yml
Normal file
21
integration/resources/compose/consul.yml
Normal file
|
@ -0,0 +1,21 @@
|
|||
consul:
|
||||
image: progrium/consul
|
||||
command: -server -bootstrap -advertise 12.0.0.254 -log-level debug -ui-dir /ui
|
||||
ports:
|
||||
- "8400:8400"
|
||||
- "8500:8500"
|
||||
- "8600:53/udp"
|
||||
expose:
|
||||
- "8300"
|
||||
- "8301"
|
||||
- "8301/udp"
|
||||
- "8302"
|
||||
- "8302/udp"
|
||||
|
||||
registrator:
|
||||
image: gliderlabs/registrator:master
|
||||
command: -internal consulkv://consul:8500/traefik
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock
|
||||
links:
|
||||
- consul
|
20
integration/resources/compose/file.yml
Normal file
20
integration/resources/compose/file.yml
Normal file
|
@ -0,0 +1,20 @@
|
|||
nginx1:
|
||||
image: nginx
|
||||
ports:
|
||||
- "8881:80"
|
||||
nginx2:
|
||||
image: nginx
|
||||
ports:
|
||||
- "8882:80"
|
||||
nginx3:
|
||||
image: nginx
|
||||
ports:
|
||||
- "8883:80"
|
||||
nginx4:
|
||||
image: nginx
|
||||
ports:
|
||||
- "8884:80"
|
||||
nginx5:
|
||||
image: nginx
|
||||
ports:
|
||||
- "8885:80"
|
42
integration/resources/compose/marathon.yml
Normal file
42
integration/resources/compose/marathon.yml
Normal file
|
@ -0,0 +1,42 @@
|
|||
zk:
|
||||
image: bobrik/zookeeper
|
||||
net: host
|
||||
environment:
|
||||
ZK_CONFIG: tickTime=2000,initLimit=10,syncLimit=5,maxClientCnxns=128,forceSync=no,clientPort=2181
|
||||
ZK_ID: 1
|
||||
|
||||
master:
|
||||
image: mesosphere/mesos-master:0.23.0-1.0.ubuntu1404
|
||||
net: host
|
||||
environment:
|
||||
MESOS_ZK: zk://127.0.0.1:2181/mesos
|
||||
MESOS_HOSTNAME: 127.0.0.1
|
||||
MESOS_IP: 127.0.0.1
|
||||
MESOS_QUORUM: 1
|
||||
MESOS_CLUSTER: docker-compose
|
||||
MESOS_WORK_DIR: /var/lib/mesos
|
||||
|
||||
slave:
|
||||
image: mesosphere/mesos-slave:0.23.0-1.0.ubuntu1404
|
||||
net: host
|
||||
pid: host
|
||||
privileged: true
|
||||
environment:
|
||||
MESOS_MASTER: zk://127.0.0.1:2181/mesos
|
||||
MESOS_HOSTNAME: 127.0.0.1
|
||||
MESOS_IP: 127.0.0.1
|
||||
MESOS_CONTAINERIZERS: docker,mesos
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup
|
||||
- /usr/bin/docker:/usr/bin/docker:ro
|
||||
- /usr/lib/x86_64-linux-gnu/libapparmor.so.1:/usr/lib/x86_64-linux-gnu/libapparmor.so.1:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
marathon:
|
||||
image: mesosphere/marathon:v0.9.2
|
||||
net: host
|
||||
environment:
|
||||
MARATHON_MASTER: zk://127.0.0.1:2181/mesos
|
||||
MARATHON_ZK: zk://127.0.0.1:2181/marathon
|
||||
MARATHON_HOSTNAME: 127.0.0.1
|
||||
command: --event_subscriber http_callback
|
Loading…
Add table
Add a link
Reference in a new issue