Skip to content

Commit 721ad2d

Browse files
test(ps): add tests for ps commands (#194)
1 parent f01c058 commit 721ad2d

2 files changed

Lines changed: 281 additions & 47 deletions

File tree

cmd/ps.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,13 @@ func (d DeisCmd) PsList(appID string, results int) error {
3737
// PsScale scales an app's processes.
3838
func (d DeisCmd) PsScale(appID string, targets []string) error {
3939
s, appID, err := load(d.ConfigFile, appID)
40-
4140
if err != nil {
4241
return err
4342
}
4443

45-
targetMap := make(map[string]int)
46-
regex := regexp.MustCompile("^([a-z0-9]+)=([0-9]+)$")
47-
48-
for _, target := range targets {
49-
if regex.MatchString(target) {
50-
captures := regex.FindStringSubmatch(target)
51-
targetMap[captures[1]], err = strconv.Atoi(captures[2])
52-
53-
if err != nil {
54-
return err
55-
}
56-
} else {
57-
return fmt.Errorf("'%s' does not match the pattern 'type=num', ex: web=2\n", target)
58-
}
44+
targetMap, err := parsePsTargets(targets)
45+
if err != nil {
46+
return err
5947
}
6048

6149
d.Printf("Scaling processes... but first, %s!\n", drinkOfChoice())
@@ -83,7 +71,6 @@ func (d DeisCmd) PsScale(appID string, targets []string) error {
8371
// PsRestart restarts an app's processes.
8472
func (d DeisCmd) PsRestart(appID, target string) error {
8573
s, appID, err := load(d.ConfigFile, appID)
86-
8774
if err != nil {
8875
return err
8976
}
@@ -152,3 +139,24 @@ func parseType(target string, appID string) (string, string) {
152139

153140
return psType, psName
154141
}
142+
143+
func parsePsTargets(targets []string) (map[string]int, error) {
144+
targetMap := make(map[string]int)
145+
regex := regexp.MustCompile("^([a-z0-9]+)=([0-9]+)$")
146+
var err error
147+
148+
for _, target := range targets {
149+
if regex.MatchString(target) {
150+
captures := regex.FindStringSubmatch(target)
151+
targetMap[captures[1]], err = strconv.Atoi(captures[2])
152+
153+
if err != nil {
154+
return nil, err
155+
}
156+
} else {
157+
return nil, fmt.Errorf("'%s' does not match the pattern 'type=num', ex: web=2\n", target)
158+
}
159+
}
160+
161+
return targetMap, nil
162+
}

cmd/ps_test.go

Lines changed: 257 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,16 @@
11
package cmd
22

33
import (
4-
"io/ioutil"
5-
"os"
6-
"path/filepath"
4+
"bytes"
5+
"fmt"
6+
"net/http"
77
"testing"
8-
)
9-
10-
func TestScaleFail(t *testing.T) {
11-
t.Parallel()
12-
13-
tmpDir, err := ioutil.TempDir("", "tmpdir")
14-
if err != nil {
15-
t.Fatalf("error creating temp directory (%s)", err)
16-
}
17-
18-
file := filepath.Join(tmpDir, "client.json")
19-
20-
data := []byte(`{"username":"test","ssl_verify":false,"controller":"http://deis.127.0.0.1.nip.io","token":"test","response_limit":0}`)
21-
if err := ioutil.WriteFile(file, data, 0644); err != nil {
22-
t.Fatal("error creating config file")
23-
}
24-
defer func() {
25-
if err := os.RemoveAll(tmpDir); err != nil {
26-
t.Fatalf("failed to remove creds file from %s (%s)", tmpDir, err)
27-
}
28-
}()
298

30-
expected := "'web=-1' does not match the pattern 'type=num', ex: web=2\n"
31-
d := DeisCmd{ConfigFile: file}
32-
actual := d.PsScale("testApp", []string{"web=-1"})
33-
if actual.Error() != expected {
34-
t.Errorf("Expected %s, Got %s", expected, actual)
35-
}
36-
}
9+
"github.com/arschles/assert"
10+
"github.com/deis/controller-sdk-go/api"
11+
"github.com/deis/controller-sdk-go/pkg/time"
12+
"github.com/deis/workflow-cli/pkg/testutil"
13+
)
3714

3815
func TestParseType(t *testing.T) {
3916
t.Parallel()
@@ -59,5 +36,254 @@ func TestParseType(t *testing.T) {
5936
if psType != "cmd" || psName != "" {
6037
t.Error("type was not cmd")
6138
}
39+
}
40+
41+
func TestPrintProcesses(t *testing.T) {
42+
var b bytes.Buffer
43+
44+
pods := []api.Pods{
45+
{
46+
Release: "v3",
47+
Name: "benign-quilting-web-4084101150-c871y",
48+
Type: "web",
49+
State: "up",
50+
Started: time.Time{},
51+
},
52+
{
53+
Release: "v3",
54+
Name: "benign-quilting-worker-4084101150-c871y",
55+
Type: "worker",
56+
State: "up",
57+
Started: time.Time{},
58+
},
59+
}
60+
61+
printProcesses("appname", pods, &b)
62+
63+
assert.Equal(t, b.String(), `=== appname Processes
64+
--- web:
65+
benign-quilting-web-4084101150-c871y up (v3)
66+
--- worker:
67+
benign-quilting-worker-4084101150-c871y up (v3)
68+
`, "output")
69+
}
70+
71+
func TestPsList(t *testing.T) {
72+
t.Parallel()
73+
cf, server, err := testutil.NewTestServerAndClient()
74+
if err != nil {
75+
t.Fatal(err)
76+
}
77+
defer server.Close()
78+
var b bytes.Buffer
79+
cmdr := DeisCmd{WOut: &b, ConfigFile: cf}
80+
81+
server.Mux.HandleFunc("/v2/apps/foo/pods/", func(w http.ResponseWriter, r *http.Request) {
82+
testutil.SetHeaders(w)
83+
fmt.Fprintf(w, `{
84+
"count": 1,
85+
"next": null,
86+
"previous": null,
87+
"results": [
88+
{
89+
"release": "v2",
90+
"type": "web",
91+
"name": "foo-web-4084101150-c871y",
92+
"state": "up",
93+
"started": "2016-02-13T00:47:52"
94+
}
95+
]
96+
}`)
97+
})
98+
99+
err = cmdr.PsList("foo", -1)
100+
assert.NoErr(t, err)
101+
102+
assert.Equal(t, b.String(), `=== foo Processes
103+
--- web:
104+
foo-web-4084101150-c871y up (v2)
105+
`, "output")
106+
}
107+
108+
type psTargetCases struct {
109+
Targets []string
110+
ExpectedError bool
111+
ExpectedMap map[string]int
112+
ExpectedMsg string
113+
}
114+
115+
func TestParsePsTargets(t *testing.T) {
116+
t.Parallel()
117+
118+
cases := []psTargetCases{
119+
{[]string{"test"}, true, nil, "'test' does not match the pattern 'type=num', ex: web=2\n"},
120+
{[]string{"test=a"}, true, nil, "'test=a' does not match the pattern 'type=num', ex: web=2\n"},
121+
{[]string{"test="}, true, nil, "'test=' does not match the pattern 'type=num', ex: web=2\n"},
122+
{[]string{"test=2"}, false, map[string]int{"test": 2}, ""},
123+
}
124+
125+
for _, check := range cases {
126+
actual, err := parsePsTargets(check.Targets)
127+
if check.ExpectedError {
128+
assert.Equal(t, err.Error(), check.ExpectedMsg, "error")
129+
} else {
130+
assert.NoErr(t, err)
131+
assert.Equal(t, actual, check.ExpectedMap, "error")
132+
}
133+
}
134+
}
135+
136+
func TestPsScale(t *testing.T) {
137+
t.Parallel()
138+
cf, server, err := testutil.NewTestServerAndClient()
139+
if err != nil {
140+
t.Fatal(err)
141+
}
142+
defer server.Close()
143+
var b bytes.Buffer
144+
cmdr := DeisCmd{WOut: &b, ConfigFile: cf}
145+
err = cmdr.PsScale("foo", []string{"test"})
146+
assert.Equal(t, err.Error(), "'test' does not match the pattern 'type=num', ex: web=2\n", "error")
147+
148+
server.Mux.HandleFunc("/v2/apps/foo/pods/", func(w http.ResponseWriter, r *http.Request) {
149+
testutil.SetHeaders(w)
150+
fmt.Fprintf(w, `{
151+
"count": 1,
152+
"next": null,
153+
"previous": null,
154+
"results": [
155+
{
156+
"release": "v2",
157+
"type": "web",
158+
"name": "foo-web-4084101150-c871y",
159+
"state": "up",
160+
"started": "2016-02-13T00:47:52"
161+
}
162+
]
163+
}`)
164+
})
165+
166+
server.Mux.HandleFunc("/v2/apps/foo/scale/", func(w http.ResponseWriter, r *http.Request) {
167+
testutil.AssertBody(t, map[string]int{"web": 1}, r)
168+
testutil.SetHeaders(w)
169+
w.WriteHeader(http.StatusNoContent)
170+
})
171+
172+
b.Reset()
173+
err = cmdr.PsScale("foo", []string{"web=1"})
174+
assert.NoErr(t, err)
175+
assert.Equal(t, testutil.StripProgress(b.String()), `Scaling processes... but first, coffee!
176+
done in 0s
177+
=== foo Processes
178+
--- web:
179+
foo-web-4084101150-c871y up (v2)
180+
`, "output")
181+
}
182+
183+
func TestPsRestart(t *testing.T) {
184+
t.Parallel()
185+
cf, server, err := testutil.NewTestServerAndClient()
186+
if err != nil {
187+
t.Fatal(err)
188+
}
189+
defer server.Close()
190+
var b bytes.Buffer
191+
cmdr := DeisCmd{WOut: &b, ConfigFile: cf}
192+
193+
server.Mux.HandleFunc("/v2/apps/foo/pods/restart/", func(w http.ResponseWriter, r *http.Request) {
194+
testutil.SetHeaders(w)
195+
fmt.Fprintf(w, `[
196+
{
197+
"release": "v2",
198+
"type": "web",
199+
"name": "foo-web-4084101150-c871y",
200+
"state": "up",
201+
"started": "2016-02-13T00:47:52"
202+
}
203+
]`)
204+
})
205+
206+
b.Reset()
207+
err = cmdr.PsRestart("foo", "")
208+
assert.NoErr(t, err)
209+
assert.Equal(t, testutil.StripProgress(b.String()), `Restarting processes... but first, coffee!
210+
done in 0s
211+
=== foo Processes
212+
--- web:
213+
foo-web-4084101150-c871y up (v2)
214+
`, "output")
215+
216+
server.Mux.HandleFunc("/v2/apps/coolapp/pods/restart/", func(w http.ResponseWriter, r *http.Request) {
217+
testutil.SetHeaders(w)
218+
fmt.Fprintf(w, `[]`)
219+
})
220+
221+
b.Reset()
222+
223+
err = cmdr.PsRestart("coolapp", "")
224+
assert.NoErr(t, err)
225+
assert.Equal(t, testutil.StripProgress(b.String()), `Restarting processes... but first, coffee!
226+
Could not find any processes to restart
227+
`, "output")
228+
229+
server.Mux.HandleFunc("/v2/apps/testapp/pods/web/restart/", func(w http.ResponseWriter, r *http.Request) {
230+
testutil.SetHeaders(w)
231+
fmt.Fprintf(w, `[
232+
{
233+
"release": "v2",
234+
"type": "web",
235+
"name": "testapp-web-4084101150-c871y",
236+
"state": "up",
237+
"started": "2016-02-13T00:47:52"
238+
}
239+
]`)
240+
})
241+
242+
b.Reset()
243+
244+
err = cmdr.PsRestart("testapp", "web")
245+
assert.NoErr(t, err)
246+
assert.Equal(t, testutil.StripProgress(b.String()), `Restarting processes... but first, coffee!
247+
done in 0s
248+
=== testapp Processes
249+
--- web:
250+
testapp-web-4084101150-c871y up (v2)
251+
`, "output")
252+
253+
server.Mux.HandleFunc("/v2/apps/newapp/pods/web/newapp-web-4084101150-c871y/restart/", func(w http.ResponseWriter, r *http.Request) {
254+
testutil.SetHeaders(w)
255+
fmt.Fprintf(w, `[
256+
{
257+
"release": "v2",
258+
"type": "web",
259+
"name": "newapp-web-4084101150-c871y",
260+
"state": "up",
261+
"started": "2016-02-13T00:47:52"
262+
}
263+
]`)
264+
})
265+
266+
b.Reset()
267+
268+
err = cmdr.PsRestart("newapp", "newapp-web-4084101150-c871y")
269+
assert.NoErr(t, err)
270+
assert.Equal(t, testutil.StripProgress(b.String()), `Restarting processes... but first, coffee!
271+
done in 0s
272+
=== newapp Processes
273+
--- web:
274+
newapp-web-4084101150-c871y up (v2)
275+
`, "output")
276+
277+
server.Mux.HandleFunc("/v2/apps/newapp/pods/ghost/restart/", func(w http.ResponseWriter, r *http.Request) {
278+
testutil.SetHeaders(w)
279+
w.WriteHeader(http.StatusBadRequest)
280+
fmt.Fprintf(w, `{
281+
"detail": "Container type ghost does not exist in application"
282+
}`)
283+
})
284+
285+
b.Reset()
62286

287+
err = cmdr.PsRestart("newapp", "ghost")
288+
assert.Equal(t, err.Error(), "Could not find process type ghost in app newapp", "error")
63289
}

0 commit comments

Comments
 (0)