Skip to content

Commit c5b9697

Browse files
committed
Merge pull request #1379 from deis/integration-tests
feat(tests): add integration tests
2 parents 0762714 + 9c2d6c0 commit c5b9697

44 files changed

Lines changed: 2643 additions & 43 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

client/deis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ def auth_cancel(self, args):
678678
self._settings.save()
679679
print('Account cancelled')
680680
else:
681-
print('Accont not changed')
681+
print('Account not changed')
682682

683683
def auth_login(self, args):
684684
"""

tests/Makefile

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
11
test:
22
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
3-
go test -tags integration -timeout 30m -v ./...
3+
go test -tags integration -v -run TestSmoke
44

55
test-smoke:
66
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
7-
go test -tags integration -timeout 10m -short -v ./...
7+
go test -tags integration -short -v -run TestSmoke
8+
9+
test-full:
10+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
11+
go test -tags integration -v -run TestGlobal
12+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
13+
go test -tags integration -v -run TestApps
14+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
15+
go test -tags integration -v -run TestAuth
16+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
17+
go test -tags integration -v -run TestBuilds
18+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
19+
go test -tags integration -v -run TestClusters
20+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
21+
go test -tags integration -v -run TestConfig
22+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
23+
go test -tags integration -v -run TestKeys
24+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
25+
go test -tags integration -v -run TestPerms
26+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
27+
go test -tags integration -v -run TestPs
28+
GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
29+
go test -tags integration -v -run TestReleases
830

931
nuke_from_orbit:
1032
-docker kill `docker ps -q`
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright (C) 2014 Thomas Rooney
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
package gexpect
2+
3+
import (
4+
"errors"
5+
shell "github.com/kballard/go-shellquote"
6+
"github.com/kr/pty"
7+
"io"
8+
"os"
9+
"os/exec"
10+
"regexp"
11+
"time"
12+
)
13+
14+
type ExpectSubprocess struct {
15+
Cmd *exec.Cmd
16+
f *os.File
17+
}
18+
19+
func SpawnAtDirectory(command string, directory string) (*ExpectSubprocess, error) {
20+
expect, err := _spawn(command)
21+
if err != nil {
22+
return nil, err
23+
}
24+
expect.Cmd.Dir = directory
25+
return _start(expect)
26+
}
27+
28+
func Command(command string) (*ExpectSubprocess, error) {
29+
expect, err := _spawn(command)
30+
if err != nil {
31+
return nil, err
32+
}
33+
return expect, nil
34+
}
35+
36+
func (expect *ExpectSubprocess) Start() error {
37+
_, err := _start(expect)
38+
return err
39+
}
40+
41+
func Spawn(command string) (*ExpectSubprocess, error) {
42+
expect, err := _spawn(command)
43+
if err != nil {
44+
return nil, err
45+
}
46+
return _start(expect)
47+
}
48+
49+
func (expect *ExpectSubprocess) Close() error {
50+
return expect.Cmd.Process.Kill()
51+
}
52+
53+
func (expect *ExpectSubprocess) AsyncInteractChannels() (send chan string, receive chan string) {
54+
receive = make(chan string)
55+
send = make(chan string)
56+
57+
go func() {
58+
for {
59+
str, err := expect.ReadLine()
60+
if err != nil {
61+
close(receive)
62+
return
63+
}
64+
receive <- str
65+
}
66+
}()
67+
68+
go func() {
69+
for {
70+
select {
71+
case sendCommand, exists := <-send:
72+
{
73+
if !exists {
74+
return
75+
}
76+
err := expect.Send(sendCommand)
77+
if err != nil {
78+
receive <- "gexpect Error: " + err.Error()
79+
return
80+
}
81+
}
82+
}
83+
}
84+
}()
85+
86+
return
87+
}
88+
89+
// This quite possibly won't work as we're operating on an incomplete stream. It might work if all the input is within one
90+
// Flush, but that can't be relied upon. I need to find a nice, safe way to apply a regex to a stream of partial content, given we
91+
// don't not knowing how long our input is, and thus can't buffer it. Until that point, please just use Expect, or use the channel
92+
// to parse the stream yourself.
93+
func (expect *ExpectSubprocess) ExpectRegex(regexSearchString string) (e error) {
94+
var size = len(regexSearchString)
95+
96+
if size < 255 {
97+
size = 255
98+
}
99+
100+
chunk := make([]byte, size)
101+
102+
for {
103+
n, err := expect.f.Read(chunk)
104+
105+
if err != nil {
106+
return err
107+
}
108+
success, err := regexp.Match(regexSearchString, chunk[:n])
109+
if err != nil {
110+
return err
111+
}
112+
if success {
113+
return nil
114+
}
115+
}
116+
}
117+
118+
func buildKMPTable(searchString string) []int {
119+
pos := 2
120+
cnd := 0
121+
length := len(searchString)
122+
123+
var table []int
124+
if length < 2 {
125+
length = 2
126+
}
127+
128+
table = make([]int, length)
129+
table[0] = -1
130+
table[1] = 0
131+
132+
for pos < len(searchString) {
133+
if searchString[pos-1] == searchString[cnd] {
134+
cnd += 1
135+
table[pos] = cnd
136+
pos += 1
137+
} else if cnd > 0 {
138+
cnd = table[cnd]
139+
} else {
140+
table[pos] = 0
141+
pos += 1
142+
}
143+
}
144+
return table
145+
}
146+
147+
func (expect *ExpectSubprocess) ExpectTimeout(searchString string, timeout time.Duration) (e error) {
148+
result := make(chan error)
149+
go func() {
150+
result <- expect.Expect(searchString)
151+
}()
152+
select {
153+
case e = <-result:
154+
case <-time.After(timeout):
155+
e = errors.New("Expect timed out.")
156+
}
157+
return e
158+
}
159+
160+
func (expect *ExpectSubprocess) Expect(searchString string) (e error) {
161+
chunk := make([]byte, len(searchString)*2)
162+
target := len(searchString)
163+
m := 0
164+
i := 0
165+
// Build KMP Table
166+
table := buildKMPTable(searchString)
167+
168+
for {
169+
n, err := expect.f.Read(chunk)
170+
171+
if err != nil {
172+
return err
173+
}
174+
offset := m + i
175+
for m+i-offset < n {
176+
if searchString[i] == chunk[m+i-offset] {
177+
i += 1
178+
if i == target {
179+
return nil
180+
}
181+
} else {
182+
m += i - table[i]
183+
if table[i] > -1 {
184+
i = table[i]
185+
} else {
186+
i = 0
187+
}
188+
}
189+
}
190+
}
191+
}
192+
193+
func (expect *ExpectSubprocess) Send(command string) error {
194+
_, err := io.WriteString(expect.f, command)
195+
return err
196+
}
197+
198+
func (expect *ExpectSubprocess) SendLine(command string) error {
199+
_, err := io.WriteString(expect.f, command+"\r\n")
200+
return err
201+
}
202+
203+
func (expect *ExpectSubprocess) Interact() {
204+
defer expect.Cmd.Wait()
205+
go io.Copy(os.Stdout, expect.f)
206+
go io.Copy(os.Stderr, expect.f)
207+
go io.Copy(expect.f, os.Stdin)
208+
}
209+
210+
func (expect *ExpectSubprocess) ReadUntil(delim byte) ([]byte, error) {
211+
join := make([]byte, 1, 512)
212+
chunk := make([]byte, 255)
213+
214+
for {
215+
216+
n, err := expect.f.Read(chunk)
217+
218+
if err != nil {
219+
return join, err
220+
}
221+
222+
for i := 0; i < n; i++ {
223+
if chunk[i] == delim {
224+
return join, nil
225+
} else {
226+
join = append(join, chunk[i])
227+
}
228+
}
229+
}
230+
}
231+
232+
func (expect *ExpectSubprocess) Wait() error {
233+
return expect.Cmd.Wait()
234+
}
235+
236+
func (expect *ExpectSubprocess) ReadLine() (string, error) {
237+
str, err := expect.ReadUntil('\n')
238+
if err != nil {
239+
return "", err
240+
}
241+
return string(str), nil
242+
}
243+
244+
func _start(expect *ExpectSubprocess) (*ExpectSubprocess, error) {
245+
f, err := pty.Start(expect.Cmd)
246+
if err != nil {
247+
return nil, err
248+
}
249+
expect.f = f
250+
251+
return expect, nil
252+
}
253+
254+
func _spawn(command string) (*ExpectSubprocess, error) {
255+
wrapper := new(ExpectSubprocess)
256+
257+
splitArgs, err := shell.Split(command)
258+
if err != nil {
259+
return nil, err
260+
}
261+
numArguments := len(splitArgs) - 1
262+
if numArguments < 0 {
263+
return nil, errors.New("gexpect: No command given to spawn")
264+
}
265+
path, err := exec.LookPath(splitArgs[0])
266+
if err != nil {
267+
return nil, err
268+
}
269+
270+
if numArguments >= 1 {
271+
wrapper.Cmd = exec.Command(path, splitArgs[1:]...)
272+
} else {
273+
wrapper.Cmd = exec.Command(path)
274+
}
275+
276+
return wrapper, nil
277+
}

0 commit comments

Comments
 (0)