Esempio n. 1
0
func (s *S) TestRebalanceContainersManyApps(c *check.C) {
	p, err := s.startMultipleServersCluster()
	c.Assert(err, check.IsNil)
	err = s.newFakeImage(p, "tsuru/app-myapp", nil)
	c.Assert(err, check.IsNil)
	err = s.newFakeImage(p, "tsuru/app-otherapp", nil)
	c.Assert(err, check.IsNil)
	appInstance := provisiontest.NewFakeApp("myapp", "python", 0)
	defer p.Destroy(appInstance)
	p.Provision(appInstance)
	appInstance2 := provisiontest.NewFakeApp("otherapp", "python", 0)
	defer p.Destroy(appInstance2)
	p.Provision(appInstance2)
	imageId, err := image.AppCurrentImageName(appInstance.GetName())
	c.Assert(err, check.IsNil)
	_, err = addContainersWithHost(&changeUnitsPipelineArgs{
		toHost:      "localhost",
		toAdd:       map[string]*containersToAdd{"web": {Quantity: 1}},
		app:         appInstance,
		imageId:     imageId,
		provisioner: p,
	})
	c.Assert(err, check.IsNil)
	imageId2, err := image.AppCurrentImageName(appInstance2.GetName())
	c.Assert(err, check.IsNil)
	_, err = addContainersWithHost(&changeUnitsPipelineArgs{
		toHost:      "localhost",
		toAdd:       map[string]*containersToAdd{"web": {Quantity: 1}},
		app:         appInstance2,
		imageId:     imageId2,
		provisioner: p,
	})
	c.Assert(err, check.IsNil)
	appStruct := &app.App{
		Name: appInstance.GetName(),
		Pool: "test-default",
	}
	err = s.storage.Apps().Insert(appStruct)
	c.Assert(err, check.IsNil)
	appStruct2 := &app.App{
		Name: appInstance2.GetName(),
		Pool: "test-default",
	}
	err = s.storage.Apps().Insert(appStruct2)
	c.Assert(err, check.IsNil)
	buf := safe.NewBuffer(nil)
	c1, err := p.listContainersByHost("localhost")
	c.Assert(err, check.IsNil)
	c.Assert(c1, check.HasLen, 2)
	err = p.rebalanceContainers(buf, false)
	c.Assert(err, check.IsNil)
	c1, err = p.listContainersByHost("localhost")
	c.Assert(err, check.IsNil)
	c.Assert(c1, check.HasLen, 1)
	c2, err := p.listContainersByHost("127.0.0.1")
	c.Assert(err, check.IsNil)
	c.Assert(c2, check.HasLen, 1)
}
Esempio n. 2
0
func (s *BindSuite) TestUnbindUnit(c *check.C) {
	called := false
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		called = true
		w.WriteHeader(http.StatusNoContent)
	}))
	defer ts.Close()
	srvc := Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}}
	err := srvc.Create()
	c.Assert(err, check.IsNil)
	defer s.conn.Services().Remove(bson.M{"_id": "mysql"})
	app := provisiontest.NewFakeApp("painkiller", "python", 1)
	units, err := app.GetUnits()
	c.Assert(err, check.IsNil)
	instance := ServiceInstance{
		Name:        "my-mysql",
		ServiceName: "mysql",
		Teams:       []string{s.team.Name},
		Apps:        []string{app.GetName()},
		Units:       []string{units[0].GetID()},
	}
	instance.Create()
	defer s.conn.ServiceInstances().Remove(bson.M{"name": "my-mysql"})
	units, err = app.GetUnits()
	c.Assert(err, check.IsNil)
	err = instance.UnbindUnit(app, units[0])
	c.Assert(err, check.IsNil)
	c.Assert(called, check.Equals, true)
	err = s.conn.ServiceInstances().Find(bson.M{"name": "my-mysql"}).One(&instance)
	c.Assert(err, check.IsNil)
	c.Assert(instance.Units, check.HasLen, 0)
}
Esempio n. 3
0
func (s *S) TestContainerAsUnit(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	expected := provision.Unit{
		ID:          "c-id",
		AppName:     "myapp",
		Type:        "python",
		Ip:          "192.168.50.4",
		Status:      provision.StatusBuilding,
		ProcessName: "web",
		Address:     &url.URL{Scheme: "http", Host: "192.168.50.4:8080"},
	}
	container := Container{
		ID:          "c-id",
		HostAddr:    "192.168.50.4",
		HostPort:    "8080",
		ProcessName: "web",
	}
	got := container.AsUnit(app)
	c.Assert(got, check.DeepEquals, expected)
	container.Type = "ruby"
	container.Status = provision.StatusStarted.String()
	got = container.AsUnit(app)
	expected.Status = provision.StatusStarted
	expected.Type = "ruby"
	c.Assert(got, check.DeepEquals, expected)
}
Esempio n. 4
0
func (s *S) TestContainerCreateDoesNotAlocatesPortForDeploy(c *check.C) {
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		Deploy:      true,
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	info, err := cont.NetworkInfo(s.p)
	c.Assert(err, check.IsNil)
	c.Assert(info.HTTPHostPort, check.Equals, "")
}
Esempio n. 5
0
func (s *S) TestRebalanceContainers(c *check.C) {
	p, err := s.startMultipleServersCluster()
	c.Assert(err, check.IsNil)
	err = s.newFakeImage(p, "tsuru/app-myapp", nil)
	c.Assert(err, check.IsNil)
	appInstance := provisiontest.NewFakeApp("myapp", "python", 0)
	defer p.Destroy(appInstance)
	p.Provision(appInstance)
	imageId, err := appCurrentImageName(appInstance.GetName())
	c.Assert(err, check.IsNil)
	_, err = addContainersWithHost(&changeUnitsPipelineArgs{
		toHost:      "localhost",
		toAdd:       map[string]*containersToAdd{"web": {Quantity: 5}},
		app:         appInstance,
		imageId:     imageId,
		provisioner: p,
	})
	c.Assert(err, check.IsNil)
	appStruct := &app.App{
		Name: appInstance.GetName(),
	}
	err = s.storage.Apps().Insert(appStruct)
	c.Assert(err, check.IsNil)
	buf := safe.NewBuffer(nil)
	err = p.rebalanceContainers(buf, false)
	c.Assert(err, check.IsNil)
	c1, err := p.listContainersByHost("localhost")
	c.Assert(err, check.IsNil)
	c2, err := p.listContainersByHost("127.0.0.1")
	c.Assert(err, check.IsNil)
	c.Assert((len(c1) == 3 && len(c2) == 2) || (len(c1) == 2 && len(c2) == 3), check.Equals, true)
}
Esempio n. 6
0
func (s *S) TestFollowLogsAndCommitForward(c *check.C) {
	err := s.newFakeImage(s.p, "tsuru/python", nil)
	c.Assert(err, check.IsNil)
	app := provisiontest.NewFakeApp("mightyapp", "python", 1)
	nextImgName, err := appNewImageName(app.GetName())
	c.Assert(err, check.IsNil)
	cont := container.Container{AppName: "mightyapp", ID: "myid123", BuildingImage: nextImgName}
	err = cont.Create(&container.CreateArgs{
		App:         app,
		ImageID:     "tsuru/python",
		Commands:    []string{"foo"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	buf := safe.NewBuffer(nil)
	args := runContainerActionsArgs{writer: buf, provisioner: s.p}
	context := action.FWContext{Params: []interface{}{args}, Previous: cont}
	imageId, err := followLogsAndCommit.Forward(context)
	c.Assert(err, check.IsNil)
	c.Assert(imageId, check.Equals, "tsuru/app-mightyapp:v1")
	c.Assert(buf.String(), check.Not(check.Equals), "")
	var dbCont container.Container
	coll := s.p.Collection()
	defer coll.Close()
	err = coll.Find(bson.M{"id": cont.ID}).One(&dbCont)
	c.Assert(err, check.NotNil)
	c.Assert(err.Error(), check.Equals, "not found")
	_, err = s.p.Cluster().InspectContainer(cont.ID)
	c.Assert(err, check.NotNil)
	c.Assert(err.Error(), check.Matches, "No such container.*")
	err = s.p.Cluster().RemoveImage("tsuru/app-mightyapp:v1")
	c.Assert(err, check.IsNil)
}
Esempio n. 7
0
func (s *S) TestProvisionAddUnitsToHostForward(c *check.C) {
	p, err := s.startMultipleServersCluster()
	c.Assert(err, check.IsNil)
	app := provisiontest.NewFakeApp("myapp-2", "python", 0)
	defer p.Destroy(app)
	p.Provision(app)
	coll := p.Collection()
	defer coll.Close()
	coll.Insert(container.Container{ID: "container-id", AppName: app.GetName(), Version: "container-version", Image: "tsuru/python"})
	defer coll.RemoveAll(bson.M{"appname": app.GetName()})
	imageId, err := appNewImageName(app.GetName())
	c.Assert(err, check.IsNil)
	err = s.newFakeImage(p, imageId, nil)
	c.Assert(err, check.IsNil)
	args := changeUnitsPipelineArgs{
		app:         app,
		toHost:      "localhost",
		toAdd:       map[string]*containersToAdd{"web": {Quantity: 2}},
		imageId:     imageId,
		provisioner: p,
	}
	context := action.FWContext{Params: []interface{}{args}}
	result, err := provisionAddUnitsToHost.Forward(context)
	c.Assert(err, check.IsNil)
	containers := result.([]container.Container)
	c.Assert(containers, check.HasLen, 2)
	c.Assert(containers[0].HostAddr, check.Equals, "localhost")
	c.Assert(containers[1].HostAddr, check.Equals, "localhost")
	count, err := coll.Find(bson.M{"appname": app.GetName()}).Count()
	c.Assert(err, check.IsNil)
	c.Assert(count, check.Equals, 3)
}
Esempio n. 8
0
func (s *S) TestRemoveOldRoutesForward(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont1 := container.Container{ID: "ble-1", AppName: app.GetName(), ProcessName: "web", HostAddr: "127.0.0.1", HostPort: "1234"}
	cont2 := container.Container{ID: "ble-2", AppName: app.GetName(), ProcessName: "web", HostAddr: "127.0.0.2", HostPort: "4321"}
	cont3 := container.Container{ID: "ble-3", AppName: app.GetName(), ProcessName: "worker", HostAddr: "127.0.0.3", HostPort: "8080"}
	defer cont1.Remove(s.p)
	defer cont2.Remove(s.p)
	defer cont3.Remove(s.p)
	err := routertest.FakeRouter.AddRoute(app.GetName(), cont1.Address())
	c.Assert(err, check.IsNil)
	err = routertest.FakeRouter.AddRoute(app.GetName(), cont2.Address())
	c.Assert(err, check.IsNil)
	args := changeUnitsPipelineArgs{
		app:         app,
		toRemove:    []container.Container{cont1, cont2, cont3},
		provisioner: s.p,
	}
	context := action.FWContext{Previous: []container.Container{}, Params: []interface{}{args}}
	r, err := removeOldRoutes.Forward(context)
	c.Assert(err, check.IsNil)
	hasRoute := routertest.FakeRouter.HasRoute(app.GetName(), cont1.Address().String())
	c.Assert(hasRoute, check.Equals, false)
	hasRoute = routertest.FakeRouter.HasRoute(app.GetName(), cont2.Address().String())
	c.Assert(hasRoute, check.Equals, false)
	containers := r.([]container.Container)
	c.Assert(containers, check.DeepEquals, []container.Container{})
	c.Assert(args.toRemove[0].Routable, check.Equals, true)
	c.Assert(args.toRemove[1].Routable, check.Equals, true)
	c.Assert(args.toRemove[2].Routable, check.Equals, false)
}
Esempio n. 9
0
func (s *S) TestArchiveDeployCanceledEvent(c *check.C) {
	err := s.newFakeImage(s.p, "tsuru/python:latest", nil)
	c.Assert(err, check.IsNil)
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	evt, err := event.New(&event.Opts{
		Target:        event.Target{Type: "app", Value: "myapp"},
		Kind:          permission.PermAppDeploy,
		Owner:         s.token,
		Cancelable:    true,
		Allowed:       event.Allowed(permission.PermApp),
		AllowedCancel: event.Allowed(permission.PermApp),
	})
	c.Assert(err, check.IsNil)
	done := make(chan bool)
	go func() {
		defer close(done)
		img, depErr := s.p.archiveDeploy(app, image.GetBuildImage(app), "https://s3.amazonaws.com/wat/archive.tar.gz", evt)
		c.Assert(depErr, check.ErrorMatches, "deploy canceled by user action")
		c.Assert(img, check.Equals, "")
	}()
	time.Sleep(100 * time.Millisecond)
	err = evt.TryCancel("because yes", "*****@*****.**")
	c.Assert(err, check.IsNil)
	<-done
}
Esempio n. 10
0
func (s *S) TestRemoveBoundEnvsForward(c *check.C) {
	a := provisiontest.NewFakeApp("myapp", "static", 4)
	srv := Service{Name: "mysql"}
	err := s.conn.Services().Insert(&srv)
	c.Assert(err, check.IsNil)
	si := ServiceInstance{Name: "my-mysql", ServiceName: "mysql", Teams: []string{s.team.Name}}
	err = s.conn.ServiceInstances().Insert(&si)
	c.Assert(err, check.IsNil)
	instance := bind.ServiceInstance{Name: si.Name, Envs: map[string]string{"ENV1": "VAL1", "ENV2": "VAL2"}}
	err = a.AddInstance(
		bind.InstanceApp{
			ServiceName:   si.ServiceName,
			Instance:      instance,
			ShouldRestart: true,
		}, nil)
	c.Assert(err, check.IsNil)
	buf := bytes.NewBuffer(nil)
	args := bindPipelineArgs{
		app:             a,
		serviceInstance: &si,
		writer:          buf,
	}
	ctx := action.FWContext{Params: []interface{}{&args}}
	_, err = removeBoundEnvs.Forward(ctx)
	c.Assert(err, check.IsNil)
	c.Assert(a.GetInstances("mysql"), check.DeepEquals, []bind.ServiceInstance{})
}
Esempio n. 11
0
func (s *S) TestContainerStart(c *check.C) {
	cont, err := s.newContainer(nil, nil)
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(cont)
	client, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	contPath := fmt.Sprintf("/containers/%s/start", cont.ID)
	defer s.server.CustomHandler(contPath, s.server.DefaultHandler())
	dockerContainer, err := client.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(dockerContainer.State.Running, check.Equals, false)
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	app.Memory = 15
	app.Swap = 15
	app.CpuShare = 10
	err = cont.start(s.p, app, false)
	c.Assert(err, check.IsNil)
	dockerContainer, err = client.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(dockerContainer.State.Running, check.Equals, true)
	expectedLogOptions := map[string]string{
		"syslog-address": "udp://localhost:1514",
	}
	expectedPortBindings := map[docker.Port][]docker.PortBinding{
		"8888/tcp": {{HostIP: "", HostPort: ""}},
	}
	c.Assert(dockerContainer.HostConfig.RestartPolicy.Name, check.Equals, "always")
	c.Assert(dockerContainer.HostConfig.LogConfig.Type, check.Equals, "syslog")
	c.Assert(dockerContainer.HostConfig.LogConfig.Config, check.DeepEquals, expectedLogOptions)
	c.Assert(dockerContainer.HostConfig.PortBindings, check.DeepEquals, expectedPortBindings)
	c.Assert(dockerContainer.HostConfig.Memory, check.Equals, int64(15))
	c.Assert(dockerContainer.HostConfig.MemorySwap, check.Equals, int64(30))
	c.Assert(dockerContainer.HostConfig.CPUShares, check.Equals, int64(10))
	c.Assert(cont.Status, check.Equals, "starting")
}
Esempio n. 12
0
func (s *S) TestContainerCreateOverwriteEntrypoint(c *check.C) {
	config.Set("host", "my.cool.tsuru.addr:8080")
	defer config.Unset("host")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		Deploy:      true,
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.Entrypoint, check.DeepEquals, []string{})
}
Esempio n. 13
0
func (s *S) TestRunContainerHealerDoesntHealWhenContainerIsRestarting(c *check.C) {
	p, err := dockertest.StartMultipleServersCluster()
	c.Assert(err, check.IsNil)
	defer p.Destroy()
	node1 := p.Servers()[0]
	app := provisiontest.NewFakeApp("myapp", "python", 0)
	cont, err := p.StartContainers(dockertest.StartContainersArgs{
		Endpoint:  node1.URL(),
		App:       app,
		Amount:    map[string]int{"web": 1},
		Image:     "tsuru/python",
		PullImage: true,
	})
	c.Assert(err, check.IsNil)
	node1.MutateContainer(cont[0].ID, docker.State{Running: false, Restarting: true})

	toMoveCont := cont[0]
	toMoveCont.LastSuccessStatusUpdate = time.Now().Add(-2 * time.Minute)
	p.PrepareListResult([]container.Container{toMoveCont}, nil)

	healer := NewContainerHealer(ContainerHealerArgs{
		Provisioner:         p,
		MaxUnresponsiveTime: time.Minute,
		Locker:              dockertest.NewFakeLocker(),
	})
	healer.runContainerHealerOnce()

	healingColl, err := healingCollection()
	c.Assert(err, check.IsNil)
	defer healingColl.Close()
	var events []HealingEvent
	err = healingColl.Find(nil).All(&events)
	c.Assert(err, check.IsNil)
	c.Assert(events, check.HasLen, 0)
}
Esempio n. 14
0
func (s *S) TestRunContainerHealerCreatedContainerNoProcess(c *check.C) {
	p, err := dockertest.StartMultipleServersCluster()
	c.Assert(err, check.IsNil)
	defer p.Destroy()
	app := provisiontest.NewFakeApp("myapp", "python", 2)
	containers, err := p.StartContainers(dockertest.StartContainersArgs{
		Endpoint:  p.Servers()[0].URL(),
		App:       app,
		Amount:    map[string]int{"web": 2},
		Image:     "tsuru/python",
		PullImage: true,
	})
	c.Assert(err, check.IsNil)
	notToMove := containers[1]
	notToMove.MongoID = bson.NewObjectIdWithTime(time.Now().Add(-2 * time.Minute))
	notToMove.ProcessName = ""
	p.PrepareListResult([]container.Container{containers[0], notToMove}, nil)
	healer := NewContainerHealer(ContainerHealerArgs{
		Provisioner:         p,
		MaxUnresponsiveTime: time.Minute,
		Locker:              dockertest.NewFakeLocker(),
	})
	healer.runContainerHealerOnce()
	movings := p.Movings()
	c.Assert(movings, check.IsNil)
	healingColl, err := healingCollection()
	c.Assert(err, check.IsNil)
	defer healingColl.Close()
	n, err := healingColl.Count()
	c.Assert(err, check.IsNil)
	c.Assert(n, check.Equals, 0)
}
Esempio n. 15
0
func (s *BindSuite) TestUnbindRemovesAppFromServiceInstance(c *check.C) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNoContent)
	}))
	defer ts.Close()
	srvc := Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}}
	err := srvc.Create()
	c.Assert(err, check.IsNil)
	defer s.conn.Services().Remove(bson.M{"_id": "mysql"})
	instance := ServiceInstance{
		Name:        "my-mysql",
		ServiceName: "mysql",
		Teams:       []string{s.team.Name},
		Apps:        []string{"painkiller"},
	}
	instance.Create()
	defer s.conn.ServiceInstances().Remove(bson.M{"name": "my-mysql"})
	app := provisiontest.NewFakeApp("painkiller", "python", 0)
	app.AddInstance(
		bind.InstanceApp{
			ServiceName:   "mysql",
			Instance:      bind.ServiceInstance{Name: "my-mysql"},
			ShouldRestart: true,
		}, ioutil.Discard)
	err = instance.UnbindApp(app, true, nil)
	c.Assert(err, check.IsNil)
	s.conn.ServiceInstances().Find(bson.M{"name": instance.Name}).One(&instance)
	c.Assert(instance.Apps, check.DeepEquals, []string{})
}
Esempio n. 16
0
func (s *S) TestAddNewRouteBackward(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont1 := container.Container{ID: "ble-1", AppName: app.GetName(), ProcessName: "web", HostAddr: "127.0.0.1", HostPort: "1234"}
	cont2 := container.Container{ID: "ble-2", AppName: app.GetName(), ProcessName: "web", HostAddr: "127.0.0.2", HostPort: "4321"}
	cont3 := container.Container{ID: "ble-3", AppName: app.GetName(), ProcessName: "worker", HostAddr: "127.0.0.3", HostPort: "8080"}
	defer cont1.Remove(s.p)
	defer cont2.Remove(s.p)
	defer cont3.Remove(s.p)
	err := routertest.FakeRouter.AddRoute(app.GetName(), cont1.Address())
	c.Assert(err, check.IsNil)
	err = routertest.FakeRouter.AddRoute(app.GetName(), cont2.Address())
	c.Assert(err, check.IsNil)
	args := changeUnitsPipelineArgs{
		app:         app,
		provisioner: s.p,
	}
	cont1.Routable = true
	cont2.Routable = true
	context := action.BWContext{FWResult: []container.Container{cont1, cont2, cont3}, Params: []interface{}{args}}
	addNewRoutes.Backward(context)
	hasRoute := routertest.FakeRouter.HasRoute(app.GetName(), cont1.Address().String())
	c.Assert(hasRoute, check.Equals, false)
	hasRoute = routertest.FakeRouter.HasRoute(app.GetName(), cont2.Address().String())
	c.Assert(hasRoute, check.Equals, false)
	hasRoute = routertest.FakeRouter.HasRoute(app.GetName(), cont3.Address().String())
	c.Assert(hasRoute, check.Equals, false)
}
Esempio n. 17
0
func (s *S) TestInsertEmptyContainerInDBForward(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	args := runContainerActionsArgs{
		app:           app,
		imageID:       "image-id",
		buildingImage: "next-image",
		provisioner:   s.p,
	}
	context := action.FWContext{Params: []interface{}{args}}
	r, err := insertEmptyContainerInDB.Forward(context)
	c.Assert(err, check.IsNil)
	cont := r.(container.Container)
	c.Assert(cont, check.FitsTypeOf, container.Container{})
	c.Assert(cont.AppName, check.Equals, app.GetName())
	c.Assert(cont.Type, check.Equals, app.GetPlatform())
	c.Assert(cont.Name, check.Not(check.Equals), "")
	c.Assert(strings.HasPrefix(cont.Name, app.GetName()+"-"), check.Equals, true)
	c.Assert(cont.Name, check.HasLen, 26)
	c.Assert(cont.Status, check.Equals, "created")
	c.Assert(cont.Image, check.Equals, "image-id")
	c.Assert(cont.BuildingImage, check.Equals, "next-image")
	coll := s.p.Collection()
	defer coll.Close()
	defer coll.Remove(bson.M{"name": cont.Name})
	var retrieved container.Container
	err = coll.Find(bson.M{"name": cont.Name}).One(&retrieved)
	c.Assert(err, check.IsNil)
	c.Assert(retrieved.Name, check.Equals, cont.Name)
}
Esempio n. 18
0
func (s *S) TestGetImageFromAppPlatform(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	img := s.p.getBuildImage(app)
	repoNamespace, err := config.GetString("docker:repository-namespace")
	c.Assert(err, check.IsNil)
	c.Assert(img, check.Equals, fmt.Sprintf("%s/python:latest", repoNamespace))
}
Esempio n. 19
0
func (s *S) TestRemoveOldRoutesForwardFailInMiddle(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont := container.Container{ID: "ble-1", AppName: app.GetName(), ProcessName: "web", HostAddr: "addr1"}
	cont2 := container.Container{ID: "ble-2", AppName: app.GetName(), ProcessName: "web", HostAddr: "addr2"}
	defer cont.Remove(s.p)
	defer cont2.Remove(s.p)
	err := routertest.FakeRouter.AddRoute(app.GetName(), cont.Address())
	c.Assert(err, check.IsNil)
	err = routertest.FakeRouter.AddRoute(app.GetName(), cont2.Address())
	c.Assert(err, check.IsNil)
	routertest.FakeRouter.FailForIp(cont2.Address().String())
	args := changeUnitsPipelineArgs{
		app:         app,
		toRemove:    []container.Container{cont, cont2},
		provisioner: s.p,
	}
	context := action.FWContext{Previous: []container.Container{}, Params: []interface{}{args}}
	_, err = removeOldRoutes.Forward(context)
	c.Assert(err, check.Equals, routertest.ErrForcedFailure)
	hasRoute := routertest.FakeRouter.HasRoute(app.GetName(), cont.Address().String())
	c.Assert(hasRoute, check.Equals, true)
	hasRoute = routertest.FakeRouter.HasRoute(app.GetName(), cont2.Address().String())
	c.Assert(hasRoute, check.Equals, true)
	c.Assert(args.toRemove[0].Routable, check.Equals, true)
	c.Assert(args.toRemove[1].Routable, check.Equals, false)
}
Esempio n. 20
0
func (s *S) TestBindAppEndpointActionForwardReturnsEnvVars(c *check.C) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`{"DATABASE_USER":"******","DATABASE_PASSWORD":"******"}`))
	}))
	defer ts.Close()
	service := Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}}
	err := service.Create()
	c.Assert(err, check.IsNil)
	defer s.conn.Services().RemoveId(service.Name)
	si := ServiceInstance{
		Name:        "my-mysql",
		ServiceName: "mysql",
		Teams:       []string{s.team.Name},
	}
	err = si.Create()
	c.Assert(err, check.IsNil)
	defer s.conn.ServiceInstances().RemoveId(si.Name)
	a := provisiontest.NewFakeApp("myapp", "static", 1)
	ctx := action.FWContext{
		Params: []interface{}{&bindPipelineArgs{app: a, serviceInstance: &si}},
	}
	envs, err := bindAppEndpointAction.Forward(ctx)
	c.Assert(err, check.IsNil)
	c.Assert(envs, check.DeepEquals, map[string]string{
		"DATABASE_USER":     "******",
		"DATABASE_PASSWORD": "******",
	})
}
Esempio n. 21
0
func (s *S) TestProvisionAddUnitsToHostForwardWithoutHost(c *check.C) {
	p, err := s.startMultipleServersCluster()
	c.Assert(err, check.IsNil)
	app := provisiontest.NewFakeApp("myapp-2", "python", 0)
	defer p.Destroy(app)
	p.Provision(app)
	coll := p.Collection()
	defer coll.Close()
	imageId, err := appNewImageName(app.GetName())
	c.Assert(err, check.IsNil)
	err = s.newFakeImage(p, imageId, nil)
	c.Assert(err, check.IsNil)
	args := changeUnitsPipelineArgs{
		app:         app,
		toAdd:       map[string]*containersToAdd{"web": {Quantity: 3}},
		imageId:     imageId,
		provisioner: p,
	}
	context := action.FWContext{Params: []interface{}{args}}
	result, err := provisionAddUnitsToHost.Forward(context)
	c.Assert(err, check.IsNil)
	containers := result.([]container.Container)
	c.Assert(containers, check.HasLen, 3)
	addrs := []string{containers[0].HostAddr, containers[1].HostAddr, containers[2].HostAddr}
	sort.Strings(addrs)
	isValid := reflect.DeepEqual(addrs, []string{"127.0.0.1", "localhost", "localhost"}) ||
		reflect.DeepEqual(addrs, []string{"127.0.0.1", "127.0.0.1", "localhost"})
	if !isValid {
		clusterNodes, _ := p.Cluster().UnfilteredNodes()
		c.Fatalf("Expected multiple hosts, got: %#v\nAvailable nodes: %#v", containers, clusterNodes)
	}
	count, err := coll.Find(bson.M{"appname": app.GetName()}).Count()
	c.Assert(err, check.IsNil)
	c.Assert(count, check.Equals, 3)
}
Esempio n. 22
0
func (s *S) TestBindAppEndpointActionBackward(c *check.C) {
	var called bool
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		called = true
		w.WriteHeader(http.StatusOK)
	}))
	defer ts.Close()
	service := Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}}
	err := service.Create()
	c.Assert(err, check.IsNil)
	defer s.conn.Services().RemoveId(service.Name)
	si := ServiceInstance{
		Name:        "my-mysql",
		ServiceName: "mysql",
		Teams:       []string{s.team.Name},
	}
	err = si.Create()
	c.Assert(err, check.IsNil)
	defer s.conn.ServiceInstances().RemoveId(si.Name)
	a := provisiontest.NewFakeApp("myapp", "static", 1)
	bwCtx := action.BWContext{
		Params:   []interface{}{&bindPipelineArgs{app: a, serviceInstance: &si}},
		FWResult: nil,
	}
	bindAppEndpointAction.Backward(bwCtx)
	c.Assert(called, check.Equals, true)
}
Esempio n. 23
0
func (s *S) TestBindAndHealthcheckBackward(c *check.C) {
	appName := "my-fake-app"
	err := s.newFakeImage(s.p, "tsuru/app-"+appName, nil)
	c.Assert(err, check.IsNil)
	fakeApp := provisiontest.NewFakeApp(appName, "python", 0)
	s.p.Provision(fakeApp)
	defer s.p.Destroy(fakeApp)
	buf := safe.NewBuffer(nil)
	args := changeUnitsPipelineArgs{
		app:         fakeApp,
		provisioner: s.p,
		writer:      buf,
		toAdd:       map[string]*containersToAdd{"web": {Quantity: 2}},
		imageId:     "tsuru/app-" + appName,
	}
	containers, err := addContainersWithHost(&args)
	c.Assert(err, check.IsNil)
	c.Assert(containers, check.HasLen, 2)
	context := action.BWContext{Params: []interface{}{args}, FWResult: containers}
	for _, c := range containers {
		u := c.AsUnit(fakeApp)
		fakeApp.BindUnit(&u)
	}
	bindAndHealthcheck.Backward(context)
	c.Assert(err, check.IsNil)
	u1 := containers[0].AsUnit(fakeApp)
	c.Assert(fakeApp.HasBind(&u1), check.Equals, false)
	u2 := containers[1].AsUnit(fakeApp)
	c.Assert(fakeApp.HasBind(&u2), check.Equals, false)
}
Esempio n. 24
0
func (s *S) TestUnbindAppEndpointBackward(c *check.C) {
	var reqs []*http.Request
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		reqs = append(reqs, r)
		w.WriteHeader(http.StatusOK)
	}))
	defer ts.Close()
	a := provisiontest.NewFakeApp("myapp", "static", 4)
	srv := Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}}
	err := s.conn.Services().Insert(&srv)
	c.Assert(err, check.IsNil)
	si := ServiceInstance{Name: "my-mysql", ServiceName: "mysql", Teams: []string{s.team.Name}}
	err = s.conn.ServiceInstances().Insert(&si)
	c.Assert(err, check.IsNil)
	buf := bytes.NewBuffer(nil)
	args := bindPipelineArgs{
		app:             a,
		serviceInstance: &si,
		writer:          buf,
	}
	ctx := action.BWContext{Params: []interface{}{&args}}
	unbindAppEndpoint.Backward(ctx)
	c.Assert(reqs, check.HasLen, 1)
	c.Assert(reqs[0].Method, check.Equals, "POST")
	c.Assert(reqs[0].URL.Path, check.Equals, "/resources/my-mysql/bind-app")
}
Esempio n. 25
0
func (s *S) TestContainerCreateSecurityOptions(c *check.C) {
	config.Set("docker:security-opts", []string{"label:type:svirt_apache", "ptrace peer=@unsecure"})
	defer config.Unset("docker:security-opts")
	app := provisiontest.NewFakeApp("app-name", "brainfuck", 1)
	app.Memory = 15
	app.Swap = 15
	app.CpuShare = 50
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	img := "tsuru/brainfuck:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.SecurityOpts, check.DeepEquals, []string{"label:type:svirt_apache", "ptrace peer=@unsecure"})
}
Esempio n. 26
0
func (s *S) TestAddNewRouteForwardFailInMiddle(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont := container.Container{ID: "ble-1", AppName: app.GetName(), ProcessName: "", HostAddr: "addr1", HostPort: "4321"}
	cont2 := container.Container{ID: "ble-2", AppName: app.GetName(), ProcessName: "", HostAddr: "addr2", HostPort: "8080"}
	defer cont.Remove(s.p)
	defer cont2.Remove(s.p)
	routertest.FakeRouter.FailForIp(cont2.Address().String())
	args := changeUnitsPipelineArgs{
		app:         app,
		provisioner: s.p,
	}
	prevContainers := []container.Container{cont, cont2}
	context := action.FWContext{Previous: prevContainers, Params: []interface{}{args}}
	_, err := addNewRoutes.Forward(context)
	c.Assert(err, check.Equals, routertest.ErrForcedFailure)
	hasRoute := routertest.FakeRouter.HasRoute(app.GetName(), cont.Address().String())
	c.Assert(hasRoute, check.Equals, false)
	hasRoute = routertest.FakeRouter.HasRoute(app.GetName(), cont2.Address().String())
	c.Assert(hasRoute, check.Equals, false)
	c.Assert(prevContainers[0].Routable, check.Equals, true)
	c.Assert(prevContainers[0].ID, check.Equals, "ble-1")
	c.Assert(prevContainers[1].Routable, check.Equals, false)
	c.Assert(prevContainers[1].ID, check.Equals, "ble-2")
}
Esempio n. 27
0
func (s *S) TestContainerCreateUndefinedUser(c *check.C) {
	oldUser, _ := config.Get("docker:user")
	defer config.Set("docker:user", oldUser)
	config.Unset("docker:user")
	img := "tsuru/python:latest"
	s.p.Cluster().PullImage(docker.PullImageOptions{Repository: img}, docker.AuthConfiguration{})
	app := provisiontest.NewFakeApp("app-name", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	cont := Container{
		Name:    "myName",
		AppName: app.GetName(),
		Type:    app.GetPlatform(),
		Status:  "created",
	}
	err := cont.Create(&CreateArgs{
		App:         app,
		ImageID:     img,
		Commands:    []string{"docker", "run"},
		Provisioner: s.p,
	})
	c.Assert(err, check.IsNil)
	defer s.removeTestContainer(&cont)
	dcli, _ := docker.NewClient(s.server.URL())
	container, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(container.Config.User, check.Equals, "")
}
Esempio n. 28
0
func (s *S) TestCreateContainerForward(c *check.C) {
	err := s.newFakeImage(s.p, "tsuru/python", nil)
	c.Assert(err, check.IsNil)
	client, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	images, err := client.ListImages(docker.ListImagesOptions{All: true})
	c.Assert(err, check.IsNil)
	cmds := []string{"ps", "-ef"}
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	cont := container.Container{Name: "myName", AppName: app.GetName(), Type: app.GetPlatform(), Status: "created"}
	args := runContainerActionsArgs{
		app:         app,
		imageID:     images[0].ID,
		commands:    cmds,
		provisioner: s.p,
	}
	context := action.FWContext{Previous: cont, Params: []interface{}{args}}
	r, err := createContainer.Forward(context)
	c.Assert(err, check.IsNil)
	cont = r.(container.Container)
	defer cont.Remove(s.p)
	c.Assert(cont, check.FitsTypeOf, container.Container{})
	c.Assert(cont.ID, check.Not(check.Equals), "")
	c.Assert(cont.HostAddr, check.Equals, "127.0.0.1")
	dcli, err := docker.NewClient(s.server.URL())
	c.Assert(err, check.IsNil)
	cc, err := dcli.InspectContainer(cont.ID)
	c.Assert(err, check.IsNil)
	c.Assert(cc.State.Running, check.Equals, false)
}
Esempio n. 29
0
func (s *S) TestBindAppBackwardCompatible(c *check.C) {
	var calls int32
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		atomic.AddInt32(&calls, 1)
		if strings.HasSuffix(r.URL.Path, "bind-app") {
			http.Error(w, "not found", http.StatusNotFound)
			return
		}
		var h TestHandler
		h.ServeHTTP(w, r)
	}))
	defer ts.Close()
	expected := map[string]string{
		"MYSQL_DATABASE_NAME": "CHICO",
		"MYSQL_HOST":          "localhost",
		"MYSQL_PORT":          "3306",
	}
	instance := ServiceInstance{Name: "her-redis", ServiceName: "redis"}
	a := provisiontest.NewFakeApp("her-app", "python", 1)
	client := &Client{endpoint: ts.URL, username: "******", password: "******"}
	env, err := client.BindApp(&instance, a)
	c.Assert(err, check.IsNil)
	c.Assert(env, check.DeepEquals, expected)
	c.Assert(atomic.LoadInt32(&calls), check.Equals, int32(2))
}
Esempio n. 30
0
func (s *S) TestAddNewRouteForwardNoWeb(c *check.C) {
	app := provisiontest.NewFakeApp("myapp", "python", 1)
	routertest.FakeRouter.AddBackend(app.GetName())
	defer routertest.FakeRouter.RemoveBackend(app.GetName())
	imageName := "tsuru/app-" + app.GetName()
	customData := map[string]interface{}{
		"processes": map[string]interface{}{
			"api": "python myapi.py",
		},
	}
	err := saveImageCustomData(imageName, customData)
	c.Assert(err, check.IsNil)
	cont1 := container.Container{ID: "ble-1", AppName: app.GetName(), ProcessName: "api", HostAddr: "127.0.0.1", HostPort: "1234"}
	cont2 := container.Container{ID: "ble-2", AppName: app.GetName(), ProcessName: "api", HostAddr: "127.0.0.2", HostPort: "4321"}
	defer cont1.Remove(s.p)
	defer cont2.Remove(s.p)
	args := changeUnitsPipelineArgs{
		app:         app,
		provisioner: s.p,
		imageId:     imageName,
	}
	context := action.FWContext{Previous: []container.Container{cont1, cont2}, Params: []interface{}{args}}
	r, err := addNewRoutes.Forward(context)
	c.Assert(err, check.IsNil)
	containers := r.([]container.Container)
	hasRoute := routertest.FakeRouter.HasRoute(app.GetName(), cont1.Address().String())
	c.Assert(hasRoute, check.Equals, true)
	hasRoute = routertest.FakeRouter.HasRoute(app.GetName(), cont2.Address().String())
	c.Assert(hasRoute, check.Equals, true)
	c.Assert(containers, check.HasLen, 2)
	c.Assert(containers[0].Routable, check.Equals, true)
	c.Assert(containers[0].ID, check.Equals, "ble-1")
	c.Assert(containers[1].Routable, check.Equals, true)
	c.Assert(containers[1].ID, check.Equals, "ble-2")
}