[marathon] Fix and extend integration tests.

- Update compose file.
- Add integration test for Marathon application deployment.
This commit is contained in:
Timo Reimann 2017-04-10 09:28:00 +02:00 committed by Ludovic Fernandez
parent 19a5ba3264
commit 64b8fc52c3
4 changed files with 159 additions and 65 deletions

View file

@ -8,7 +8,8 @@ TRAEFIK_ENVS := \
-e VERSION \ -e VERSION \
-e CODENAME \ -e CODENAME \
-e TESTDIRS \ -e TESTDIRS \
-e CI -e CI \
-e CONTAINER=DOCKER # Indicator for integration tests that we are running inside a container.
SRCS = $(shell git ls-files '*.go' | grep -v '^vendor/' | grep -v '^integration/vendor/') SRCS = $(shell git ls-files '*.go' | grep -v '^vendor/' | grep -v '^integration/vendor/')

View file

@ -1,9 +1,15 @@
defaultEntryPoints = ["http"] defaultEntryPoints = ["http"]
logLevel = "DEBUG"
[entryPoints] [entryPoints]
[entryPoints.http] [entryPoints.http]
address = ":8000" address = ":8000"
logLevel = "DEBUG" [web]
address = ":9090"
[marathon] [marathon]
endpoint = "{{.MarathonURL}}"
watch = true
exposedByDefault = true

View file

@ -1,53 +1,129 @@
package integration package integration
import ( import (
"fmt"
"net/http" "net/http"
"os"
"time" "time"
"github.com/containous/traefik/integration/try" "github.com/containous/traefik/integration/try"
"github.com/containous/traefik/types"
marathon "github.com/gambol99/go-marathon"
"github.com/go-check/check" "github.com/go-check/check"
checker "github.com/vdemeester/shakers" checker "github.com/vdemeester/shakers"
) )
const (
containerNameMesosSlave = "mesos-slave"
containerNameMarathon = "marathon"
)
// Marathon test suites (using libcompose) // Marathon test suites (using libcompose)
type MarathonSuite struct{ BaseSuite } type MarathonSuite struct {
BaseSuite
marathonURL string
}
func (s *MarathonSuite) SetUpSuite(c *check.C) { func (s *MarathonSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "marathon") s.createComposeProject(c, "marathon")
s.composeProject.Start(c) s.composeProject.Start(c)
// FIXME Doesn't work... marathonIPAddr := s.composeProject.Container(c, containerNameMarathon).NetworkSettings.IPAddress
//// "github.com/gambol99/go-marathon" c.Assert(marathonIPAddr, checker.Not(checker.HasLen), 0)
//config := marathon.NewDefaultConfig() s.marathonURL = "http://" + marathonIPAddr + ":8080"
//
//marathonClient, err := marathon.NewClient(config) // Wait for Marathon readiness prior to creating the client so that we
//if err != nil { // don't run into the "all cluster members down" state right from the
// c.Fatalf("Error creating Marathon client. %v", err) // start.
//} err := try.GetRequest(s.marathonURL+"/v2/leader", 1*time.Minute, try.StatusCodeIs(http.StatusOK))
// c.Assert(err, checker.IsNil)
//// Wait for Marathon to elect itself leader
//err = try.Do(30*time.Second, func() error { // Add entry for Mesos slave container IP address in the hosts file so
// leader, err := marathonClient.Leader() // that Traefik can properly forward traffic.
// // This is necessary as long as we are still using the docker-compose v1
// if err != nil || len(leader) == 0 { // spec. Once we switch to v2 or higher, we can have both the test/builder
// return fmt.Errorf("Leader not found. %v", err) // container and the Mesos slave container join the same custom network and
// } // enjoy DNS-discoverable container host names.
// mesosSlaveIPAddr := s.composeProject.Container(c, containerNameMesosSlave).NetworkSettings.IPAddress
// return nil c.Assert(mesosSlaveIPAddr, checker.Not(checker.HasLen), 0)
//}) err = s.extendDockerHostsFile(containerNameMesosSlave, mesosSlaveIPAddr)
// c.Assert(err, checker.IsNil)
//c.Assert(err, checker.IsNil)
} }
func (s *MarathonSuite) TestSimpleConfiguration(c *check.C) { // extendDockerHostsFile extends the hosts file (/etc/hosts) by the given
cmd, _ := s.cmdTraefik(withConfigFile("fixtures/marathon/simple.toml")) // host/IP address mapping if we are running inside a container.
func (s *MarathonSuite) extendDockerHostsFile(host, ipAddr string) error {
const hostsFile = "/etc/hosts"
// Determine if the run inside a container. The most reliable way to
// do this is to inject an indicator, which we do in terms of an
// environment variable.
// (See also https://groups.google.com/d/topic/docker-user/JOGE7AnJ3Gw/discussion.)
if os.Getenv("CONTAINER") == "DOCKER" {
// We are running inside a container -- extend the hosts file.
file, err := os.OpenFile(hostsFile, os.O_APPEND|os.O_WRONLY, 0600)
if err != nil {
return err
}
defer file.Close()
if _, err = file.WriteString(fmt.Sprintf("%s\t%s\n", ipAddr, host)); err != nil {
return err
}
}
return nil
}
func (s *MarathonSuite) TestConfigurationUpdate(c *check.C) {
// Start Traefik.
file := s.adaptFile(c, "fixtures/marathon/simple.toml", struct {
MarathonURL string
}{s.marathonURL})
defer os.Remove(file)
cmd, output := s.cmdTraefik(withConfigFile(file))
err := cmd.Start() err := cmd.Start()
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
defer cmd.Process.Kill() defer cmd.Process.Kill()
// TODO validate : run on 80 // Wait for Traefik to turn ready.
// Expected a 404 as we did not configure anything err = try.GetRequest("http://127.0.0.1:8000/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound))
err = try.GetRequest("http://127.0.0.1:8000/", 500*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
// Prepare Marathon client.
config := marathon.NewDefaultConfig()
config.URL = s.marathonURL
client, err := marathon.NewClient(config)
c.Assert(err, checker.IsNil)
// Show the Traefik log if any assertion fails. If the entire test runs
// to a successful completion, we flip the flag at the very end and don't
// display anything.
showTraefikLog := true
defer func() {
if showTraefikLog {
s.displayTraefikLog(c, output)
}
}()
// Create test application to be deployed.
app := marathon.NewDockerApplication().
Name("/whoami").
CPU(0.1).
Memory(32).
AddLabel(types.LabelFrontendRule, "PathPrefix:/service")
app.Container.Docker.Bridged().
Expose(80).
Container("emilevauge/whoami")
// Deploy the test application.
deploy, err := client.UpdateApplication(app, false)
c.Assert(err, checker.IsNil)
// Wait for deployment to complete.
c.Assert(client.WaitOnDeployment(deploy.DeploymentID, 1*time.Minute), checker.IsNil)
// Query application via Traefik.
err = try.GetRequest("http://127.0.0.1:8000/service", 30*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
showTraefikLog = false
} }

View file

@ -1,43 +1,54 @@
zk: zookeeper:
image: bobrik/zookeeper image: zookeeper:3.4.10
net: host
environment:
ZK_CONFIG: tickTime=2000,initLimit=10,syncLimit=5,maxClientCnxns=128,forceSync=no,clientPort=2181
ZK_ID: " 1"
master: mesos-master:
image: mesosphere/mesos-master:0.28.1-2.0.20.ubuntu1404 links:
net: host - zookeeper
image: mesosphere/mesos-master:1.0.1-2.0.93.ubuntu1404
# Uncomment published ports for interactive debugging.
# ports:
# - "5050:5050"
environment: environment:
MESOS_ZK: zk://127.0.0.1:2181/mesos - MESOS_HOSTNAME=mesos-master
MESOS_HOSTNAME: 127.0.0.1 - MESOS_CLUSTER=local
MESOS_IP: 127.0.0.1 - MESOS_REGISTRY=in_memory
MESOS_QUORUM: " 1" - MESOS_LOG_DIR=/var/log
MESOS_CLUSTER: docker-compose - MESOS_WORK_DIR=/var/lib/mesos
MESOS_WORK_DIR: /var/lib/mesos - MESOS_ZK=zk://zookeeper:2181/mesos
slave: mesos-slave:
image: mesosphere/mesos-slave:0.28.1-2.0.20.ubuntu1404 links:
net: host - zookeeper
pid: host - mesos-master
image: mesosphere/mesos-slave-dind:0.3.0_mesos-1.0.1_docker-1.10.3_ubuntu-14.04.5
privileged: true privileged: true
# Uncomment published ports for interactive debugging.
# ports:
# - "5051:5051"
environment: environment:
MESOS_MASTER: zk://127.0.0.1:2181/mesos - MESOS_HOSTNAME=mesos-slave
MESOS_HOSTNAME: 127.0.0.1 - MESOS_CONTAINERIZERS=docker,mesos
MESOS_IP: 127.0.0.1 - MESOS_ISOLATOR=cgroups/cpu,cgroups/mem
MESOS_CONTAINERIZERS: docker,mesos - MESOS_LOG_DIR=/var/log
volumes: - MESOS_MASTER=zk://zookeeper:2181/mesos
- /sys/fs/cgroup:/sys/fs/cgroup - MESOS_PORT=5051
- /usr/bin/docker:/usr/bin/docker:ro - MESOS_WORK_DIR=/var/lib/mesos
- /usr/lib/x86_64-linux-gnu/libapparmor.so.1:/usr/lib/x86_64-linux-gnu/libapparmor.so.1:ro - MESOS_EXECUTOR_REGISTRATION_TIMEOUT=5mins
- /var/run/docker.sock:/var/run/docker.sock - MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=90secs
- /lib/x86_64-linux-gnu/libsystemd-journal.so.0:/lib/x86_64-linux-gnu/libsystemd-journal.so.0 - MESOS_DOCKER_STOP_TIMEOUT=60secs
- MESOS_RESOURCES=cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]
marathon: marathon:
image: mesosphere/marathon:v1.1.1 links:
net: host - zookeeper
- mesos-master
- mesos-slave
image: mesosphere/marathon:v1.3.12
# Uncomment published ports for interactive debugging.
# ports:
# - "8080:8080"
extra_hosts:
- "mesos-slave:172.17.0.1"
environment: environment:
MARATHON_MASTER: zk://127.0.0.1:2181/mesos - MARATHON_ZK=zk://zookeeper:2181/marathon
MARATHON_ZK: zk://127.0.0.1:2181/marathon - MARATHON_MASTER=zk://zookeeper:2181/mesos
MARATHON_HOSTNAME: 127.0.0.1
command: --event_subscriber http_callback