func TestFormationList(t *testing.T) { models.Test(t, func() { formation := structs.Formation{ structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}}, structs.ProcessFormation{Name: "worker", Count: 3, CPU: 129, Memory: 1025, Ports: []int{4000, 4001}}, } models.TestProvider.On("FormationList", "myapp").Return(formation, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/apps/myapp/formation", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, `[ {"balancer":"", "count":2, "cpu":128, "memory":1024, "name":"web", "ports":[3000,3001]}, {"balancer":"", "count":3, "cpu":129, "memory":1025, "name":"worker", "ports":[4000,4001]} ]`) } }) models.Test(t, func() { models.TestProvider.On("FormationList", "myapp").Return(nil, fmt.Errorf("some error")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/apps/myapp/formation", nil)) { hf.AssertCode(t, 500) hf.AssertError(t, "some error") } }) }
func TestProcessStop(t *testing.T) { models.Test(t, func() { models.TestProvider.On("ProcessStop", "myapp-staging", "p1234").Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("DELETE", "/apps/myapp-staging/processes/p1234", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, `{"success":true}`) } }) models.Test(t, func() { models.TestProvider.On("ProcessStop", "myapp-staging", "p1234").Return(test.ErrorNotFound("no such process")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("DELETE", "/apps/myapp-staging/processes/p1234", nil)) { hf.AssertCode(t, 404) hf.AssertError(t, "no such process") } }) models.Test(t, func() { models.TestProvider.On("ProcessStop", "myapp-staging", "p1234").Return(fmt.Errorf("unknown error")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("DELETE", "/apps/myapp-staging/processes/p1234", nil)) { hf.AssertCode(t, 500) hf.AssertError(t, "unknown error") } }) }
func TestProcessList(t *testing.T) { models.Test(t, func() { processes := structs.Processes{ structs.Process{ ID: "foo", App: "myapp-staging", Name: "procname", Release: "R123", Command: "ls -la", Host: "127.0.0.1", Image: "image:tag", Instance: "i-1234", Ports: []string{"80", "443"}, CPU: 0.345, Memory: 0.456, Started: time.Unix(1473483567, 0).UTC(), }, } models.TestProvider.On("ProcessList", "myapp-staging").Return(processes, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/apps/myapp-staging/processes", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, "[{\"app\":\"myapp-staging\",\"command\":\"ls -la\",\"cpu\":0.345,\"host\":\"127.0.0.1\",\"id\":\"foo\",\"image\":\"image:tag\",\"instance\":\"i-1234\",\"memory\":0.456,\"name\":\"procname\",\"ports\":[\"80\",\"443\"],\"release\":\"R123\",\"started\":\"2016-09-10T04:59:27Z\"}]") } }) models.Test(t, func() { models.TestProvider.On("ProcessList", "myapp-staging").Return(nil, test.ErrorNotFound("no such process")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/apps/myapp-staging/processes", nil)) { hf.AssertCode(t, 404) hf.AssertError(t, "no such process") } }) models.Test(t, func() { models.TestProvider.On("ProcessList", "myapp-staging").Return(nil, fmt.Errorf("unknown error")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/apps/myapp-staging/processes", nil)) { hf.AssertCode(t, 500) hf.AssertError(t, "unknown error") } }) }
func TestFormationSetNonNumeric(t *testing.T) { models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "foo") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 403) hf.AssertError(t, "count must be numeric") } }) models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("cpu", "foo") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 403) hf.AssertError(t, "cpu must be numeric") } }) models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("memory", "foo") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 403) hf.AssertError(t, "memory must be numeric") } }) }
func TestInstanceList(t *testing.T) { models.Test(t, func() { instances := structs.Instances{ structs.Instance{ Agent: true, Cpu: 0.28, Id: "test", Memory: 0.18, PrivateIp: "1.2.3.4", Processes: 5, PublicIp: "2.3.4.5", Status: "running", Started: time.Unix(1475610360, 0).UTC(), }, } models.TestProvider.On("InstanceList").Return(instances, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/instances", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, "[{\"agent\":true,\"cpu\":0.28,\"id\":\"test\",\"memory\":0.18,\"private-ip\":\"1.2.3.4\",\"processes\":5,\"public-ip\":\"2.3.4.5\",\"started\":\"2016-10-04T19:46:00Z\",\"status\":\"running\"}]") } }) }
func TestReleaseList(t *testing.T) { models.Test(t, func() { releases := structs.Releases{ structs.Release{ Id: "RVFETUHHKKD", App: "httpd", Build: "BHINCLZYYVN", Env: "foo=bar", Manifest: "web:\n image: httpd\n ports:\n - 80:80\n", Created: time.Unix(1459780542, 627770380).UTC(), }, structs.Release{ Id: "RFVZFLKVTYO", App: "httpd", Build: "BNOARQMVHUO", Env: "foo=bar", Manifest: "web:\n image: httpd\n ports:\n - 80:80\n", Created: time.Unix(1459709199, 166694813).UTC(), }, } models.TestProvider.On("ReleaseList", "example", int64(20)).Return(releases, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/apps/example/releases", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, "[{\"app\":\"httpd\",\"build\":\"BHINCLZYYVN\",\"created\":\"2016-04-04T14:35:42.62777038Z\",\"env\":\"foo=bar\",\"id\":\"RVFETUHHKKD\",\"manifest\":\"web:\\n image: httpd\\n ports:\\n - 80:80\\n\"},{\"app\":\"httpd\",\"build\":\"BNOARQMVHUO\",\"created\":\"2016-04-03T18:46:39.166694813Z\",\"env\":\"foo=bar\",\"id\":\"RFVZFLKVTYO\",\"manifest\":\"web:\\n image: httpd\\n ports:\\n - 80:80\\n\"}]") } }) }
func TestBuildDelete(t *testing.T) { models.Test(t, func() { build := &structs.Build{ App: "myapp", Description: "desc", Ended: time.Unix(1475611334, 0).UTC(), Id: "B1234", Logs: "", Manifest: "", Reason: "", Release: "R2345", Started: time.Unix(1475611334, 0).UTC(), Status: "complete", } models.TestProvider.On("ReleaseDelete", "example", "B1234").Return(nil) models.TestProvider.On("BuildDelete", "example", "B1234").Return(build, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("DELETE", "/apps/example/builds/B1234", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, "{\"app\":\"myapp\",\"description\":\"desc\",\"ended\":\"2016-10-04T20:02:14Z\",\"id\":\"B1234\",\"logs\":\"\",\"manifest\":\"\",\"reason\":\"\",\"release\":\"R2345\",\"started\":\"2016-10-04T20:02:14Z\",\"status\":\"complete\"}") } }) }
func TestSystemUpdateAutoscaleCount(t *testing.T) { models.Test(t, func() { as := os.Getenv("AUTOSCALE") os.Setenv("AUTOSCALE", "true") defer os.Setenv("AUTOSCALE", as) before := &structs.System{ Count: 3, Name: "test", Region: "us-test-1", Status: "running", Type: "t2.small", Version: "dev", } models.TestProvider.On("SystemGet").Return(before, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "5") if assert.Nil(t, hf.Request("PUT", "/system", v)) { hf.AssertCode(t, 403) hf.AssertError(t, "scaling count prohibited when autoscale enabled") } }) }
func TestSystemUpdateSaveError(t *testing.T) { models.Test(t, func() { before := &structs.System{ Count: 3, Name: "test", Region: "us-test-1", Status: "running", Type: "t2.small", Version: "dev", } change := structs.System{ Count: 4, Name: "test", Region: "us-test-1", Status: "running", Type: "t2.small", Version: "dev", } models.TestProvider.On("SystemGet").Return(before, nil) models.TestProvider.On("SystemSave", change).Return(fmt.Errorf("bad save")) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "4") if assert.Nil(t, hf.Request("PUT", "/system", v)) { hf.AssertCode(t, 500) hf.AssertError(t, "bad save") } }) }
func TestSystemUpdate(t *testing.T) { models.Test(t, func() { before := &structs.System{ Count: 3, Name: "test", Region: "us-test-1", Status: "running", Type: "t2.small", Version: "dev", } change := structs.System{ Count: 5, Name: "test", Region: "us-test-1", Status: "running", Type: "t2.test", Version: "latest", } models.TestProvider.On("SystemGet").Return(before, nil) models.TestProvider.On("SystemSave", change).Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "5") v.Add("type", "t2.test") v.Add("version", "latest") if assert.Nil(t, hf.Request("PUT", "/system", v)) { hf.AssertCode(t, 200) hf.AssertJSON(t, `{"count":5,"name":"test","region":"us-test-1","status":"running","type":"t2.test","version":"latest"}`) } }) }
func TestSystemUpdateBadCount(t *testing.T) { models.Test(t, func() { before := &structs.System{ Count: 3, Name: "test", Region: "us-test-1", Status: "running", Type: "t2.small", Version: "dev", } models.TestProvider.On("SystemGet").Return(before, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "foo") if assert.Nil(t, hf.Request("PUT", "/system", v)) { hf.AssertCode(t, 403) hf.AssertError(t, "count must be numeric") } }) models.Test(t, func() { before := &structs.System{ Count: 3, Name: "test", Region: "us-test-1", Status: "running", Type: "t2.small", Version: "dev", } models.TestProvider.On("SystemGet").Return(before, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "-2") if assert.Nil(t, hf.Request("PUT", "/system", v)) { hf.AssertCode(t, 403) hf.AssertError(t, "count must be greater than 1") } }) }
func TestProcessRunDetached(t *testing.T) { opts := structs.ProcessRunOptions{ Command: "test-command", Release: "R1234", } v := url.Values{} v.Add("command", "test-command") v.Add("release", "R1234") models.Test(t, func() { models.TestProvider.On("ProcessRun", "myapp-staging", "web", opts).Return("pid", nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("POST", "/apps/myapp-staging/processes/web/run", v)) { hf.AssertCode(t, 200) hf.AssertJSON(t, `{"success":true}`) } }) models.Test(t, func() { models.TestProvider.On("ProcessRun", "myapp-staging", "web", opts).Return("", test.ErrorNotFound("no such process")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("POST", "/apps/myapp-staging/processes/web/run", v)) { hf.AssertCode(t, 404) hf.AssertError(t, "no such process") } }) models.Test(t, func() { models.TestProvider.On("ProcessRun", "myapp-staging", "web", opts).Return("", fmt.Errorf("unknown error")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("POST", "/apps/myapp-staging/processes/web/run", v)) { hf.AssertCode(t, 500) hf.AssertError(t, "unknown error") } }) }
func TestFormationListError(t *testing.T) { models.TestProvider = &provider.TestProvider{} models.TestProvider.On("FormationList", "myapp").Return(nil, fmt.Errorf("some error")) hf := test.NewHandlerFunc(controllers.HandlerFunc) hf.Request("GET", "/apps/myapp/formation", nil) hf.AssertCode(t, 500) hf.AssertError(t, "some error") models.TestProvider.AssertExpectations(t) }
func TestSystemUpdateRackFetchError(t *testing.T) { models.Test(t, func() { models.TestProvider.On("SystemGet").Return(nil, fmt.Errorf("some error")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("PUT", "/system", nil)) { hf.AssertCode(t, 500) hf.AssertError(t, "some error") } }) }
func TestSystemReleasesError(t *testing.T) { models.Test(t, func() { models.TestProvider.On("SystemReleases").Return(nil, fmt.Errorf("some error")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/system/releases", nil)) { hf.AssertCode(t, 500) hf.AssertError(t, "some error") } }) }
func TestInstanceTerminate(t *testing.T) { models.Test(t, func() { models.TestProvider.On("InstanceTerminate", "i-1234").Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("DELETE", "/instances/i-1234", nil)) { hf.AssertCode(t, 200) hf.AssertSuccess(t) } }) models.Test(t, func() { models.TestProvider.On("InstanceTerminate", "i-1234").Return(fmt.Errorf("broken")) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("DELETE", "/instances/i-1234", nil)) { hf.AssertCode(t, 500) hf.AssertError(t, "broken") } }) }
func TestFormationSetFailedGet(t *testing.T) { models.Test(t, func() { models.TestProvider.On("FormationGet", "myapp", "web").Return(nil, fmt.Errorf("could not fetch")) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "4") v.Add("cpu", "200") v.Add("memory", "300") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 500) hf.AssertError(t, "could not fetch") } }) }
func TestFormationSetOne(t *testing.T) { models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} after := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 200, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) models.TestProvider.On("FormationSave", "myapp", after).Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("cpu", "200") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 200) hf.AssertSuccess(t) } }) }
func TestSystemReleases(t *testing.T) { models.Test(t, func() { releases := structs.Releases{ structs.Release{Id: "R0000001", App: "test", Build: "B0000001", Created: time.Date(2016, 3, 4, 5, 6, 7, 12, time.UTC)}, structs.Release{Id: "R0000002", App: "test", Build: "B0000002", Created: time.Date(2016, 3, 4, 9, 6, 7, 14, time.UTC)}, } models.TestProvider.On("SystemReleases").Return(releases, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/system/releases", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, `[ {"app":"test","build":"B0000001","created":"2016-03-04T05:06:07.000000012Z","env":"","id":"R0000001","manifest":""}, {"app":"test","build":"B0000002","created":"2016-03-04T09:06:07.000000014Z","env":"","id":"R0000002","manifest":""} ]`) } }) }
func TestSystemShow(t *testing.T) { models.Test(t, func() { system := &structs.System{ Count: 3, Name: "test", Region: "us-test-1", Status: "running", Type: "t2.small", Version: "dev", } models.TestProvider.On("SystemGet").Return(system, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/system", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, `{"count":3,"name":"test","region":"us-test-1","status":"running","type":"t2.small","version":"dev"}`) } }) }
func TestSystemCapacity(t *testing.T) { models.Test(t, func() { capacity := &structs.Capacity{ ClusterCPU: 200, ClusterMemory: 2048, InstanceCPU: 100, InstanceMemory: 2048, ProcessCount: 10, ProcessMemory: 1928, ProcessCPU: 84, ProcessWidth: 3, } models.TestProvider.On("CapacityGet").Return(capacity, nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) if assert.Nil(t, hf.Request("GET", "/system/capacity", nil)) { hf.AssertCode(t, 200) hf.AssertJSON(t, `{"cluster-cpu":200,"cluster-memory":2048,"instance-cpu":100,"instance-memory":2048,"process-count":10,"process-memory":1928,"process-cpu":84,"process-width":3}`) } }) }
func TestFormationSetEdgeCases(t *testing.T) { // count=-1 with older rack versions means no change models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} after := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 200, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) models.TestProvider.On("FormationSave", "myapp", after).Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) hf.SetVersion("20160602213112") v := url.Values{} v.Add("count", "-1") v.Add("cpu", "200") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 200) hf.AssertSuccess(t) } }) // count=-2 means no change models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} after := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 200, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) models.TestProvider.On("FormationSave", "myapp", after).Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "-2") v.Add("cpu", "200") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 200) hf.AssertSuccess(t) } }) // cpu=-1 means no change models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} after := &structs.ProcessFormation{Name: "web", Count: 4, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) models.TestProvider.On("FormationSave", "myapp", after).Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "4") v.Add("cpu", "-1") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 200) hf.AssertSuccess(t) } }) // memory=0 means no change models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} after := &structs.ProcessFormation{Name: "web", Count: 4, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) models.TestProvider.On("FormationSave", "myapp", after).Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "4") v.Add("memory", "0") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 200) hf.AssertSuccess(t) } }) // memory=-1 means no change models.Test(t, func() { before := &structs.ProcessFormation{Name: "web", Count: 2, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} after := &structs.ProcessFormation{Name: "web", Count: 4, CPU: 128, Memory: 1024, Ports: []int{3000, 3001}} models.TestProvider.On("FormationGet", "myapp", "web").Return(before, nil) models.TestProvider.On("FormationSave", "myapp", after).Return(nil) hf := test.NewHandlerFunc(controllers.HandlerFunc) v := url.Values{} v.Add("count", "4") v.Add("memory", "-1") if assert.Nil(t, hf.Request("POST", "/apps/myapp/formation/web", v)) { hf.AssertCode(t, 200) hf.AssertSuccess(t) } }) }