OLD | NEW |
1 package server_test | 1 package server_test |
2 | 2 |
3 import ( | 3 import ( |
4 "bytes" | |
5 "fmt" | 4 "fmt" |
6 "io/ioutil" | 5 "io/ioutil" |
7 . "launchpad.net/gocheck" | 6 . "launchpad.net/gocheck" |
8 "launchpad.net/juju/go/cmd/jujuc/server" | 7 "launchpad.net/juju/go/cmd/jujuc/server" |
9 "launchpad.net/juju/go/log" | |
10 stdlog "log" | |
11 "os" | 8 "os" |
12 "path/filepath" | 9 "path/filepath" |
13 "strings" | 10 "strings" |
14 "testing" | 11 "testing" |
15 ) | 12 ) |
16 | 13 |
17 func Test(t *testing.T) { TestingT(t) } | 14 func Test(t *testing.T) { TestingT(t) } |
18 | 15 |
19 type LogSuite struct{} | 16 type GetCommandSuite struct{} |
20 | 17 |
21 var _ = Suite(&LogSuite{}) | 18 var _ = Suite(&GetCommandSuite{}) |
22 | 19 |
23 func pushLog(debug bool) (buf *bytes.Buffer, pop func()) { | 20 var getCommandTests = []struct { |
24 » oldTarget, oldDebug := log.Target, log.Debug | 21 » name string |
25 » buf = new(bytes.Buffer) | 22 » err string |
26 » log.Target, log.Debug = stdlog.New(buf, "", 0), debug | 23 }{ |
27 » return buf, func() { | 24 » {"juju-log", ""}, |
28 » » log.Target, log.Debug = oldTarget, oldDebug | 25 » {"random", "unknown command: random"}, |
| 26 } |
| 27 |
| 28 func (s *GetCommandSuite) TestGetCommand(c *C) { |
| 29 » ctx := &server.Context{} |
| 30 » for _, t := range getCommandTests { |
| 31 » » com, err := ctx.GetCommand(t.name) |
| 32 » » if t.err == "" { |
| 33 » » » // At this level, just check basic sanity; commands are
tested in |
| 34 » » » // more detail elsewhere. |
| 35 » » » c.Assert(com.Info().Name, Equals, t.name) |
| 36 » » » c.Assert(err, IsNil) |
| 37 » » } else { |
| 38 » » » c.Assert(com, IsNil) |
| 39 » » » c.Assert(err, ErrorMatches, t.err) |
| 40 » » } |
29 } | 41 } |
30 } | 42 } |
31 | 43 |
32 func AssertLog(c *C, ctx *server.Context, badge string, logDebug, callDebug, exp
ectMsg bool) { | 44 type RunHookSuite struct { |
33 » buf, pop := pushLog(logDebug) | |
34 » defer pop() | |
35 » msg := "the chickens are restless" | |
36 » ctx.Log(callDebug, msg) | |
37 » expect := "" | |
38 » if expectMsg { | |
39 » » var logBadge string | |
40 » » if callDebug { | |
41 » » » logBadge = "JUJU:DEBUG" | |
42 » » } else { | |
43 » » » logBadge = "JUJU" | |
44 » » } | |
45 » » expect = fmt.Sprintf("%s %s: %s\n", logBadge, badge, msg) | |
46 » } | |
47 » c.Assert(buf.String(), Equals, expect) | |
48 } | |
49 | |
50 func AssertLogs(c *C, ctx *server.Context, badge string) { | |
51 » AssertLog(c, ctx, badge, true, true, true) | |
52 » AssertLog(c, ctx, badge, true, false, true) | |
53 » AssertLog(c, ctx, badge, false, true, false) | |
54 » AssertLog(c, ctx, badge, false, false, true) | |
55 } | |
56 | |
57 func (s *LogSuite) TestLog(c *C) { | |
58 » local := &server.Context{LocalUnitName: "minecraft/0"} | |
59 » AssertLogs(c, local, "minecraft/0") | |
60 » relation := &server.Context{LocalUnitName: "minecraft/0", RelationName:
"bot"} | |
61 » AssertLogs(c, relation, "minecraft/0 bot") | |
62 } | |
63 | |
64 type ExecSuite struct { | |
65 outPath string | 45 outPath string |
66 } | 46 } |
67 | 47 |
68 var _ = Suite(&ExecSuite{}) | 48 var _ = Suite(&RunHookSuite{}) |
69 | 49 |
70 // makeCharm constructs a fake charm dir containing a single named hook with | 50 // makeCharm constructs a fake charm dir containing a single named hook with |
71 // permissions perm and exit code code. It returns the charm directory and the | 51 // permissions perm and exit code code. It returns the charm directory and the |
72 // path to which the hook script will write environment variables. | 52 // path to which the hook script will write environment variables. |
73 func makeCharm(c *C, hookName string, perm os.FileMode, code int) (charmDir, out
Path string) { | 53 func makeCharm(c *C, hookName string, perm os.FileMode, code int) (charmDir, out
Path string) { |
74 charmDir = c.MkDir() | 54 charmDir = c.MkDir() |
75 hooksDir := filepath.Join(charmDir, "hooks") | 55 hooksDir := filepath.Join(charmDir, "hooks") |
76 err := os.Mkdir(hooksDir, 0755) | 56 err := os.Mkdir(hooksDir, 0755) |
77 c.Assert(err, IsNil) | 57 c.Assert(err, IsNil) |
78 hook, err := os.OpenFile(filepath.Join(hooksDir, hookName), os.O_CREATE|
os.O_WRONLY, perm) | 58 hook, err := os.OpenFile(filepath.Join(hooksDir, hookName), os.O_CREATE|
os.O_WRONLY, perm) |
(...skipping 25 matching lines...) Expand all Loading... |
104 c.Assert(err, IsNil) | 84 c.Assert(err, IsNil) |
105 lines := strings.Split(string(out), "\n") | 85 lines := strings.Split(string(out), "\n") |
106 AssertEnvContains(c, lines, env) | 86 AssertEnvContains(c, lines, env) |
107 AssertEnvContains(c, lines, map[string]string{ | 87 AssertEnvContains(c, lines, map[string]string{ |
108 "PATH": os.Getenv("PATH"), | 88 "PATH": os.Getenv("PATH"), |
109 "DEBIAN_FRONTEND": "noninteractive", | 89 "DEBIAN_FRONTEND": "noninteractive", |
110 "APT_LISTCHANGES_FRONTEND": "none", | 90 "APT_LISTCHANGES_FRONTEND": "none", |
111 }) | 91 }) |
112 } | 92 } |
113 | 93 |
114 func (s *ExecSuite) TestNoHook(c *C) { | 94 func (s *RunHookSuite) TestNoHook(c *C) { |
115 ctx := &server.Context{} | 95 ctx := &server.Context{} |
116 err := ctx.RunHook("tree-fell-in-forest", c.MkDir(), "") | 96 err := ctx.RunHook("tree-fell-in-forest", c.MkDir(), "") |
117 c.Assert(err, IsNil) | 97 c.Assert(err, IsNil) |
118 } | 98 } |
119 | 99 |
120 func (s *ExecSuite) TestNonExecutableHook(c *C) { | 100 func (s *RunHookSuite) TestNonExecutableHook(c *C) { |
121 ctx := &server.Context{} | 101 ctx := &server.Context{} |
122 charmDir, _ := makeCharm(c, "something-happened", 0600, 0) | 102 charmDir, _ := makeCharm(c, "something-happened", 0600, 0) |
123 err := ctx.RunHook("something-happened", charmDir, "") | 103 err := ctx.RunHook("something-happened", charmDir, "") |
124 c.Assert(err, ErrorMatches, `exec: ".*/something-happened": permission d
enied`) | 104 c.Assert(err, ErrorMatches, `exec: ".*/something-happened": permission d
enied`) |
125 } | 105 } |
126 | 106 |
127 func (s *ExecSuite) TestBadHook(c *C) { | 107 func (s *RunHookSuite) TestBadHook(c *C) { |
128 ctx := &server.Context{Id: "ctx-id"} | 108 ctx := &server.Context{Id: "ctx-id"} |
129 charmDir, outPath := makeCharm(c, "occurrence-occurred", 0700, 99) | 109 charmDir, outPath := makeCharm(c, "occurrence-occurred", 0700, 99) |
130 socketPath := "/path/to/socket" | 110 socketPath := "/path/to/socket" |
131 err := ctx.RunHook("occurrence-occurred", charmDir, socketPath) | 111 err := ctx.RunHook("occurrence-occurred", charmDir, socketPath) |
132 c.Assert(err, ErrorMatches, "exit status 99") | 112 c.Assert(err, ErrorMatches, "exit status 99") |
133 AssertEnv(c, outPath, map[string]string{ | 113 AssertEnv(c, outPath, map[string]string{ |
134 "CHARM_DIR": charmDir, | 114 "CHARM_DIR": charmDir, |
135 "JUJU_AGENT_SOCKET": socketPath, | 115 "JUJU_AGENT_SOCKET": socketPath, |
136 "JUJU_CONTEXT_ID": "ctx-id", | 116 "JUJU_CONTEXT_ID": "ctx-id", |
137 }) | 117 }) |
138 } | 118 } |
139 | 119 |
140 func (s *ExecSuite) TestGoodHookWithVars(c *C) { | 120 func (s *RunHookSuite) TestGoodHookWithVars(c *C) { |
141 ctx := &server.Context{ | 121 ctx := &server.Context{ |
142 Id: "some-id", | 122 Id: "some-id", |
143 LocalUnitName: "local/99", | 123 LocalUnitName: "local/99", |
144 RemoteUnitName: "remote/123", | 124 RemoteUnitName: "remote/123", |
145 RelationName: "rel", | 125 RelationName: "rel", |
146 } | 126 } |
147 charmDir, outPath := makeCharm(c, "something-happened", 0700, 0) | 127 charmDir, outPath := makeCharm(c, "something-happened", 0700, 0) |
148 socketPath := "/path/to/socket" | 128 socketPath := "/path/to/socket" |
149 err := ctx.RunHook("something-happened", charmDir, socketPath) | 129 err := ctx.RunHook("something-happened", charmDir, socketPath) |
150 c.Assert(err, IsNil) | 130 c.Assert(err, IsNil) |
151 AssertEnv(c, outPath, map[string]string{ | 131 AssertEnv(c, outPath, map[string]string{ |
152 "CHARM_DIR": charmDir, | 132 "CHARM_DIR": charmDir, |
153 "JUJU_AGENT_SOCKET": socketPath, | 133 "JUJU_AGENT_SOCKET": socketPath, |
154 "JUJU_CONTEXT_ID": "some-id", | 134 "JUJU_CONTEXT_ID": "some-id", |
155 "JUJU_UNIT_NAME": "local/99", | 135 "JUJU_UNIT_NAME": "local/99", |
156 "JUJU_REMOTE_UNIT": "remote/123", | 136 "JUJU_REMOTE_UNIT": "remote/123", |
157 "JUJU_RELATION": "rel", | 137 "JUJU_RELATION": "rel", |
158 }) | 138 }) |
159 } | 139 } |
OLD | NEW |