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) }
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) }
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) }
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, "") }
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) }
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) }
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) }
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) }
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 }
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{}) }
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") }
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{}) }
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) }
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) }
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{}) }
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) }
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) }
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)) }
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) }
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": "******", }) }
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) }
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) }
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) }
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") }
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"}) }
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") }
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, "") }
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) }
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)) }
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") }