blob: af499a82d20239f7a06b51fb98848564c41dd737 [file] [log] [blame]
Jiri Simsa5293dcb2014-05-10 09:56:38 -07001package signals
2
3import (
Cosmos Nicolaoucc581722014-10-07 12:45:39 -07004 "bufio"
Jiri Simsa5293dcb2014-05-10 09:56:38 -07005 "fmt"
Cosmos Nicolaoucc581722014-10-07 12:45:39 -07006 "io"
Jiri Simsa5293dcb2014-05-10 09:56:38 -07007 "os"
Cosmos Nicolaoucc581722014-10-07 12:45:39 -07008 "path/filepath"
9 "runtime"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070010 "syscall"
11 "testing"
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070012 "time"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070013
Jiri Simsa764efb72014-12-25 20:57:03 -080014 "v.io/core/veyron2"
Suharsh Sivakumar946f64d2015-01-08 10:48:13 -080015 "v.io/core/veyron2/context"
Jiri Simsa764efb72014-12-25 20:57:03 -080016 "v.io/core/veyron2/ipc"
17 "v.io/core/veyron2/mgmt"
18 "v.io/core/veyron2/naming"
Jiri Simsa764efb72014-12-25 20:57:03 -080019 "v.io/core/veyron2/services/mgmt/appcycle"
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -080020 "v.io/core/veyron2/vtrace"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070021
Jiri Simsa764efb72014-12-25 20:57:03 -080022 "v.io/core/veyron/lib/expect"
Jiri Simsa764efb72014-12-25 20:57:03 -080023 "v.io/core/veyron/lib/modules"
24 "v.io/core/veyron/lib/testutil"
Suharsh Sivakumard68949c2015-01-26 10:32:23 -080025 _ "v.io/core/veyron/profiles"
Jiri Simsa764efb72014-12-25 20:57:03 -080026 vflag "v.io/core/veyron/security/flag"
27 "v.io/core/veyron/services/mgmt/device"
Jiri Simsa5293dcb2014-05-10 09:56:38 -070028)
29
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070030// TestHelperProcess is boilerplate for the modules setup.
Jiri Simsa5293dcb2014-05-10 09:56:38 -070031func TestHelperProcess(t *testing.T) {
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070032 modules.DispatchInTest()
Jiri Simsa5293dcb2014-05-10 09:56:38 -070033}
34
35func init() {
Asim Shankarc920db32014-10-16 19:18:21 -070036 testutil.Init()
Cosmos Nicolaou1e78ccc2014-10-09 08:10:26 -070037 modules.RegisterChild("handleDefaults", "", handleDefaults)
38 modules.RegisterChild("handleCustom", "", handleCustom)
39 modules.RegisterChild("handleCustomWithStop", "", handleCustomWithStop)
40 modules.RegisterChild("handleDefaultsIgnoreChan", "", handleDefaultsIgnoreChan)
Jiri Simsa5293dcb2014-05-10 09:56:38 -070041}
42
Suharsh Sivakumard68949c2015-01-26 10:32:23 -080043func stopLoop(stop func(), stdin io.Reader, ch chan<- struct{}) {
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070044 scanner := bufio.NewScanner(stdin)
45 for scanner.Scan() {
46 switch scanner.Text() {
Jiri Simsa5293dcb2014-05-10 09:56:38 -070047 case "close":
48 close(ch)
49 return
50 case "stop":
Suharsh Sivakumard68949c2015-01-26 10:32:23 -080051 stop()
Jiri Simsa5293dcb2014-05-10 09:56:38 -070052 }
53 }
54}
55
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070056func program(stdin io.Reader, stdout io.Writer, signals ...os.Signal) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -080057 ctx, shutdown := veyron2.Init()
Suharsh Sivakumar946f64d2015-01-08 10:48:13 -080058
Jiri Simsa5293dcb2014-05-10 09:56:38 -070059 closeStopLoop := make(chan struct{})
Suharsh Sivakumard68949c2015-01-26 10:32:23 -080060 go stopLoop(veyron2.GetAppCycle(ctx).Stop, stdin, closeStopLoop)
Suharsh Sivakumar946f64d2015-01-08 10:48:13 -080061 wait := ShutdownOnSignals(ctx, signals...)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070062 fmt.Fprintf(stdout, "ready\n")
63 fmt.Fprintf(stdout, "received signal %s\n", <-wait)
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -080064 shutdown()
Jiri Simsa5293dcb2014-05-10 09:56:38 -070065 <-closeStopLoop
66}
67
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070068func handleDefaults(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
69 program(stdin, stdout)
70 return nil
Jiri Simsa5293dcb2014-05-10 09:56:38 -070071}
72
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070073func handleCustom(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
74 program(stdin, stdout, syscall.SIGABRT)
75 return nil
Jiri Simsa5293dcb2014-05-10 09:56:38 -070076}
77
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070078func handleCustomWithStop(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
79 program(stdin, stdout, STOP, syscall.SIGABRT, syscall.SIGHUP)
80 return nil
Bogdan Caprita1002ba42014-06-06 19:24:40 -070081}
82
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070083func handleDefaultsIgnoreChan(stdin io.Reader, stdout, stderr io.Writer, env map[string]string, args ...string) error {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -080084 ctx, shutdown := veyron2.Init()
85 defer shutdown()
Suharsh Sivakumar946f64d2015-01-08 10:48:13 -080086
Jiri Simsa5293dcb2014-05-10 09:56:38 -070087 closeStopLoop := make(chan struct{})
Suharsh Sivakumard68949c2015-01-26 10:32:23 -080088 go stopLoop(veyron2.GetAppCycle(ctx).Stop, stdin, closeStopLoop)
Suharsh Sivakumar946f64d2015-01-08 10:48:13 -080089 ShutdownOnSignals(ctx)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070090 fmt.Fprintf(stdout, "ready\n")
Jiri Simsa5293dcb2014-05-10 09:56:38 -070091 <-closeStopLoop
Cosmos Nicolaoucc581722014-10-07 12:45:39 -070092 return nil
Jiri Simsa5293dcb2014-05-10 09:56:38 -070093}
94
95func isSignalInSet(sig os.Signal, set []os.Signal) bool {
96 for _, s := range set {
97 if sig == s {
98 return true
99 }
100 }
101 return false
102}
103
104func checkSignalIsDefault(t *testing.T, sig os.Signal) {
105 if !isSignalInSet(sig, defaultSignals()) {
106 t.Errorf("signal %s not in default signal set, as expected", sig)
107 }
108}
109
110func checkSignalIsNotDefault(t *testing.T, sig os.Signal) {
111 if isSignalInSet(sig, defaultSignals()) {
112 t.Errorf("signal %s unexpectedly in default signal set", sig)
113 }
114}
115
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800116func newShell(t *testing.T, ctx *context.T, command string) (*modules.Shell, modules.Handle, *expect.Session) {
117 sh, err := modules.NewShell(ctx, nil)
Cosmos Nicolaou344cc4a2014-11-26 15:38:43 -0800118 if err != nil {
119 t.Fatalf("unexpected error: %s", err)
120 }
Cosmos Nicolaou612ad382014-10-29 19:41:35 -0700121 handle, err := sh.Start(command, nil)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700122 if err != nil {
123 sh.Cleanup(os.Stderr, os.Stderr)
124 t.Fatalf("unexpected error: %s", err)
125 return nil, nil, nil
126 }
127 session := expect.NewSession(t, handle.Stdout(), time.Minute)
128 return sh, handle, session
129}
130
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700131// TestCleanShutdownSignal verifies that sending a signal to a child that
132// handles it by default causes the child to shut down cleanly.
133func TestCleanShutdownSignal(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800134 ctx, shutdown := veyron2.Init()
135 defer shutdown()
136
137 sh, h, s := newShell(t, ctx, "handleDefaults")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700138 defer sh.Cleanup(os.Stderr, os.Stderr)
139 s.Expect("ready")
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700140 checkSignalIsDefault(t, syscall.SIGINT)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700141 syscall.Kill(h.Pid(), syscall.SIGINT)
142 s.Expectf("received signal %s", syscall.SIGINT)
143 fmt.Fprintf(h.Stdin(), "close\n")
144 s.ExpectEOF()
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700145}
146
147// TestCleanShutdownStop verifies that sending a stop comamnd to a child that
148// handles stop commands by default causes the child to shut down cleanly.
149func TestCleanShutdownStop(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800150 ctx, shutdown := veyron2.Init()
151 defer shutdown()
152
153 sh, h, s := newShell(t, ctx, "handleDefaults")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700154 defer sh.Cleanup(os.Stderr, os.Stderr)
155 s.Expect("ready")
156 fmt.Fprintf(h.Stdin(), "stop\n")
157 s.Expectf("received signal %s", veyron2.LocalStop)
158 fmt.Fprintf(h.Stdin(), "close\n")
159 s.ExpectEOF()
160
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700161}
162
Bogdan Caprita1002ba42014-06-06 19:24:40 -0700163// TestCleanShutdownStopCustom verifies that sending a stop comamnd to a child
164// that handles stop command as part of a custom set of signals handled, causes
165// the child to shut down cleanly.
166func TestCleanShutdownStopCustom(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800167 ctx, shutdown := veyron2.Init()
168 defer shutdown()
169
170 sh, h, s := newShell(t, ctx, "handleCustomWithStop")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700171 defer sh.Cleanup(os.Stderr, os.Stderr)
172 s.Expect("ready")
173 fmt.Fprintf(h.Stdin(), "stop\n")
174 s.Expectf("received signal %s", veyron2.LocalStop)
175 fmt.Fprintf(h.Stdin(), "close\n")
176 s.ExpectEOF()
177}
178
179func testExitStatus(t *testing.T, h modules.Handle, s *expect.Session, code int) {
180 s.ExpectEOF()
181 _, file, line, _ := runtime.Caller(1)
182 file = filepath.Base(file)
183 if got, want := h.Shutdown(os.Stdout, os.Stderr), fmt.Errorf("exit status %d", code); got.Error() != want.Error() {
184 t.Errorf("%s:%d: got %q, want %q", file, line, got, want)
185 }
Bogdan Caprita1002ba42014-06-06 19:24:40 -0700186}
187
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700188// TestStopNoHandler verifies that sending a stop command to a child that does
189// not handle stop commands causes the child to exit immediately.
190func TestStopNoHandler(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800191 ctx, shutdown := veyron2.Init()
192 defer shutdown()
193
194 sh, h, s := newShell(t, ctx, "handleCustom")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700195 defer sh.Cleanup(os.Stderr, os.Stderr)
196 s.Expect("ready")
197 fmt.Fprintf(h.Stdin(), "stop\n")
198 testExitStatus(t, h, s, veyron2.UnhandledStopExitCode)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700199}
200
201// TestDoubleSignal verifies that sending a succession of two signals to a child
202// that handles these signals by default causes the child to exit immediately
203// upon receiving the second signal.
204func TestDoubleSignal(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800205 ctx, shutdown := veyron2.Init()
206 defer shutdown()
207
208 sh, h, s := newShell(t, ctx, "handleDefaults")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700209 defer sh.Cleanup(os.Stderr, os.Stderr)
210 s.Expect("ready")
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700211 checkSignalIsDefault(t, syscall.SIGTERM)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700212 syscall.Kill(h.Pid(), syscall.SIGTERM)
213 s.Expectf("received signal %s", syscall.SIGTERM)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700214 checkSignalIsDefault(t, syscall.SIGINT)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700215 syscall.Kill(h.Pid(), syscall.SIGINT)
216 testExitStatus(t, h, s, DoubleStopExitCode)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700217}
218
219// TestSignalAndStop verifies that sending a signal followed by a stop command
220// to a child that handles these by default causes the child to exit immediately
221// upon receiving the stop command.
222func TestSignalAndStop(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800223 ctx, shutdown := veyron2.Init()
224 defer shutdown()
225
226 sh, h, s := newShell(t, ctx, "handleDefaults")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700227 defer sh.Cleanup(os.Stderr, os.Stderr)
228 s.Expect("ready")
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700229 checkSignalIsDefault(t, syscall.SIGTERM)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700230 syscall.Kill(h.Pid(), syscall.SIGTERM)
231 s.Expectf("received signal %s", syscall.SIGTERM)
232 fmt.Fprintf(h.Stdin(), "stop\n")
233 testExitStatus(t, h, s, DoubleStopExitCode)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700234}
235
236// TestDoubleStop verifies that sending a succession of stop commands to a child
237// that handles stop commands by default causes the child to exit immediately
238// upon receiving the second stop command.
239func TestDoubleStop(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800240 ctx, shutdown := veyron2.Init()
241 defer shutdown()
242
243 sh, h, s := newShell(t, ctx, "handleDefaults")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700244 defer sh.Cleanup(os.Stderr, os.Stderr)
245 s.Expect("ready")
246 fmt.Fprintf(h.Stdin(), "stop\n")
247 s.Expectf("received signal %s", veyron2.LocalStop)
248 fmt.Fprintf(h.Stdin(), "stop\n")
249 testExitStatus(t, h, s, DoubleStopExitCode)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700250}
251
252// TestSendUnhandledSignal verifies that sending a signal that the child does
253// not handle causes the child to exit as per the signal being sent.
254func TestSendUnhandledSignal(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800255 ctx, shutdown := veyron2.Init()
256 defer shutdown()
257
258 sh, h, s := newShell(t, ctx, "handleDefaults")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700259 defer sh.Cleanup(os.Stderr, os.Stderr)
260 s.Expect("ready")
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700261 checkSignalIsNotDefault(t, syscall.SIGABRT)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700262 syscall.Kill(h.Pid(), syscall.SIGABRT)
263 testExitStatus(t, h, s, 2)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700264}
265
266// TestDoubleSignalIgnoreChan verifies that, even if we ignore the channel that
267// ShutdownOnSignals returns, sending two signals should still cause the
268// process to exit (ensures that there is no dependency in ShutdownOnSignals
269// on having a goroutine read from the returned channel).
270func TestDoubleSignalIgnoreChan(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800271 ctx, shutdown := veyron2.Init()
272 defer shutdown()
273
274 sh, h, s := newShell(t, ctx, "handleDefaultsIgnoreChan")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700275 defer sh.Cleanup(os.Stderr, os.Stderr)
276 s.Expect("ready")
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700277 // Even if we ignore the channel that ShutdownOnSignals returns,
278 // sending two signals should still cause the process to exit.
279 checkSignalIsDefault(t, syscall.SIGTERM)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700280 syscall.Kill(h.Pid(), syscall.SIGTERM)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700281 checkSignalIsDefault(t, syscall.SIGINT)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700282 syscall.Kill(h.Pid(), syscall.SIGINT)
283 testExitStatus(t, h, s, DoubleStopExitCode)
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700284}
285
286// TestHandlerCustomSignal verifies that sending a non-default signal to a
287// server that listens for that signal causes the server to shut down cleanly.
288func TestHandlerCustomSignal(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800289 ctx, shutdown := veyron2.Init()
290 defer shutdown()
291
292 sh, h, s := newShell(t, ctx, "handleCustom")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700293 defer sh.Cleanup(os.Stderr, os.Stderr)
294 s.Expect("ready")
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700295 checkSignalIsNotDefault(t, syscall.SIGABRT)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700296 syscall.Kill(h.Pid(), syscall.SIGABRT)
297 s.Expectf("received signal %s", syscall.SIGABRT)
298 fmt.Fprintf(h.Stdin(), "stop\n")
299 s.ExpectEOF()
Jiri Simsa5293dcb2014-05-10 09:56:38 -0700300}
Bogdan Caprita1002ba42014-06-06 19:24:40 -0700301
302// TestHandlerCustomSignalWithStop verifies that sending a custom stop signal
303// to a server that listens for that signal causes the server to shut down
304// cleanly, even when a STOP signal is also among the handled signals.
305func TestHandlerCustomSignalWithStop(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800306 rootCtx, shutdown := veyron2.Init()
307 defer shutdown()
308
Jiri Simsa7fc6e872014-06-09 09:22:53 -0700309 for _, signal := range []syscall.Signal{syscall.SIGABRT, syscall.SIGHUP} {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800310 ctx, _ := vtrace.SetNewTrace(rootCtx)
311 sh, h, s := newShell(t, ctx, "handleCustomWithStop")
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700312 s.Expect("ready")
Bogdan Caprita1002ba42014-06-06 19:24:40 -0700313 checkSignalIsNotDefault(t, signal)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700314 syscall.Kill(h.Pid(), signal)
315 s.Expectf("received signal %s", signal)
316 fmt.Fprintf(h.Stdin(), "close\n")
317 s.ExpectEOF()
318 sh.Cleanup(os.Stderr, os.Stderr)
Bogdan Caprita1002ba42014-06-06 19:24:40 -0700319 }
320}
321
322// TestParseSignalsList verifies that ShutdownOnSignals correctly interprets
323// the input list of signals.
324func TestParseSignalsList(t *testing.T) {
325 list := []os.Signal{STOP, syscall.SIGTERM}
Matt Rosencrantzc7fecf12014-11-27 19:58:43 -0800326 ShutdownOnSignals(nil, list...)
Bogdan Caprita1002ba42014-06-06 19:24:40 -0700327 if !isSignalInSet(syscall.SIGTERM, list) {
328 t.Errorf("signal %s not in signal set, as expected: %v", syscall.SIGTERM, list)
329 }
330 if !isSignalInSet(STOP, list) {
331 t.Errorf("signal %s not in signal set, as expected: %v", STOP, list)
332 }
333}
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700334
335type configServer struct {
336 ch chan<- string
337}
338
339func (c *configServer) Set(_ ipc.ServerContext, key, value string) error {
340 if key != mgmt.AppCycleManagerConfigKey {
341 return fmt.Errorf("Unexpected key: %v", key)
342 }
343 c.ch <- value
344 return nil
345
346}
347
Matt Rosencrantzf541b772015-01-13 07:58:59 -0800348func createConfigServer(t *testing.T, ctx *context.T) (ipc.Server, string, <-chan string) {
349 server, err := veyron2.NewServer(ctx)
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700350 if err != nil {
351 t.Fatalf("Got error: %v", err)
352 }
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700353 ch := make(chan string)
Cosmos Nicolaou28dabfc2014-12-15 22:51:07 -0800354 var ep []naming.Endpoint
Suharsh Sivakumard68949c2015-01-26 10:32:23 -0800355 if ep, err = server.Listen(veyron2.GetListenSpec(ctx)); err != nil {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700356 t.Fatalf("Got error: %v", err)
357 }
Bogdan Capritaa456f472014-12-10 10:18:03 -0800358 if err := server.Serve("", device.ConfigServer(&configServer{ch}), vflag.NewAuthorizerOrDie()); err != nil {
Cosmos Nicolaoufdc838b2014-06-30 21:44:27 -0700359 t.Fatalf("Got error: %v", err)
360 }
Cosmos Nicolaou8bd8e102015-01-13 21:52:53 -0800361 return server, ep[0].Name(), ch
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700362
363}
364
365// TestCleanRemoteShutdown verifies that remote shutdown works correctly.
366func TestCleanRemoteShutdown(t *testing.T) {
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800367 ctx, shutdown := veyron2.Init()
368 defer shutdown()
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700369
Suharsh Sivakumar19fbf992015-01-23 11:02:27 -0800370 sh, err := modules.NewShell(ctx, nil)
Cosmos Nicolaou344cc4a2014-11-26 15:38:43 -0800371 if err != nil {
372 t.Fatalf("unexpected error: %s", err)
373 }
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700374 defer sh.Cleanup(os.Stderr, os.Stderr)
375
Matt Rosencrantzf541b772015-01-13 07:58:59 -0800376 configServer, configServiceName, ch := createConfigServer(t, ctx)
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700377 defer configServer.Stop()
Jiri Simsa37893392014-11-07 10:55:45 -0800378 sh.SetConfigKey(mgmt.ParentNameConfigKey, configServiceName)
379 sh.SetConfigKey(mgmt.ProtocolConfigKey, "tcp")
380 sh.SetConfigKey(mgmt.AddressConfigKey, "127.0.0.1:0")
Cosmos Nicolaou612ad382014-10-29 19:41:35 -0700381 h, err := sh.Start("handleDefaults", nil)
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700382 if err != nil {
383 t.Fatalf("unexpected error: %s", err)
384 }
385 s := expect.NewSession(t, h.Stdout(), time.Minute)
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700386 appCycleName := <-ch
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700387 s.Expect("ready")
Todd Wang702385a2014-11-07 01:54:08 -0800388 appCycle := appcycle.AppCycleClient(appCycleName)
Matt Rosencrantzf541b772015-01-13 07:58:59 -0800389 stream, err := appCycle.Stop(ctx)
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700390 if err != nil {
391 t.Fatalf("Got error: %v", err)
392 }
Shyam Jayaraman97b9dca2014-07-31 13:30:46 -0700393 rStream := stream.RecvStream()
394 if rStream.Advance() || rStream.Err() != nil {
395 t.Errorf("Expected EOF, got (%v, %v) instead: ", rStream.Value(), rStream.Err())
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700396 }
397 if err := stream.Finish(); err != nil {
398 t.Fatalf("Got error: %v", err)
399 }
Cosmos Nicolaoucc581722014-10-07 12:45:39 -0700400 s.Expectf("received signal %s", veyron2.RemoteStop)
401 fmt.Fprintf(h.Stdin(), "close\n")
402 s.ExpectEOF()
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700403}