-
Notifications
You must be signed in to change notification settings - Fork 9
/
boxsuite.go
127 lines (107 loc) · 2.92 KB
/
boxsuite.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package testsuite
import (
"bytes"
"io"
"strings"
"github.com/noxiouz/stout/isolate"
"golang.org/x/net/context"
check "gopkg.in/check.v1"
)
// RegisterSuite registers a new suite for a provided box
func RegisterSuite(boxConstructor BoxConstructor, opts isolate.Profile, skipCheck SkipCheck) {
check.Suite(&BoxSuite{
Constructor: boxConstructor,
SkipCheck: skipCheck,
opts: opts,
ctx: context.Background(),
})
}
// SkipCheck returns a reason to skip the suite
type SkipCheck func() (reason string)
// BoxConstructor returns a Box to be tested
type BoxConstructor func(c *check.C) (isolate.Box, error)
// NeverSkip is predifened SkipCheck to mark a tester never skipped
var NeverSkip SkipCheck = func() string { return "" }
// BoxSuite is a suite with specification tests for various Box implementations
type BoxSuite struct {
Constructor BoxConstructor
SkipCheck
isolate.Box
opts isolate.Profile
ctx context.Context
}
// SetUpSuite sets up the gocheck test suite.
func (suite *BoxSuite) SetUpSuite(c *check.C) {
if reason := suite.SkipCheck(); reason != "" {
c.Skip(reason)
}
b, err := suite.Constructor(c)
c.Assert(err, check.IsNil)
suite.Box = b
}
// TearDownSuite closes the Box
func (suite *BoxSuite) TearDownSuite(c *check.C) {
if suite.Box != nil {
suite.Box.Close()
}
}
// TestSpawn spool code, spawns special worker.sh to verify if env and args are set correctly and
// output is collected properly
func (suite *BoxSuite) TestSpawn(c *check.C) {
var (
ctx = context.Background()
name = "worker"
executable = "worker.sh"
args = map[string]string{
"--uuid": "some_uuid",
"--locator": "127.0.0.1:10053",
"--endpoint": "/var/run/cocaine.sock",
"--app": "appname",
}
env = map[string]string{
"enva": "a",
"envb": "b",
}
)
err := suite.Box.Spool(ctx, name, suite.opts)
c.Assert(err, check.IsNil)
pr, err := suite.Box.Spawn(ctx, suite.opts, name, executable, args, env)
c.Assert(err, check.IsNil)
defer pr.Kill()
// collect output
first := true
body := new(bytes.Buffer)
for inc := range pr.Output() {
c.Assert(inc.Err, check.IsNil)
if first {
// first chunk must be empty according to the spec
// to notify cocaine-runtime that worker has been launched
first = false
c.Assert(inc.Data, check.HasLen, 0)
}
body.Write(inc.Data)
}
// verify args
unsplittedArgs, err := body.ReadString('\n')
c.Assert(err, check.IsNil)
cargs := strings.Split(strings.Trim(unsplittedArgs, "\n"), " ")
c.Assert(cargs, check.HasLen, len(args)*2)
for i := 0; i < len(cargs); {
c.Assert(args[cargs[i]], check.Equals, cargs[i+1])
i += 2
}
// verify env
cenv := make(map[string]string)
for {
envline, err := body.ReadString('\n')
if err == io.EOF {
break
}
envs := strings.Split(envline[:len(envline)-1], "=")
c.Assert(envs, check.HasLen, 2)
cenv[envs[0]] = envs[1]
}
for k, v := range env {
c.Assert(cenv[k], check.Equals, v)
}
}