Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(225)

Delta Between Two Patch Sets: cmd/jujuc/server/server_test.go

Issue 6120054: RPC server for remote command invocation
Left Patch Set: RPC server for remote command invocation Created 12 years, 11 months ago
Right Patch Set: RPC server for remote command invocation Created 12 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « cmd/jujuc/server/server.go ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 package server_test 1 package server_test
2 2
3 import ( 3 import (
4 "errors" 4 "errors"
5 "fmt" 5 "fmt"
6 "io/ioutil" 6 "io/ioutil"
7 "launchpad.net/gnuflag" 7 "launchpad.net/gnuflag"
8 . "launchpad.net/gocheck" 8 . "launchpad.net/gocheck"
9 "launchpad.net/juju/go/cmd" 9 "launchpad.net/juju/go/cmd"
10 "launchpad.net/juju/go/cmd/jujuc/server" 10 "launchpad.net/juju/go/cmd/jujuc/server"
11 "net/rpc" 11 "net/rpc"
12 "os" 12 "os"
13 "path/filepath" 13 "path/filepath"
14 "strings"
15 ) 14 )
16 15
17 type RpcCommand struct { 16 type RpcCommand struct {
18 Value string 17 Value string
19 } 18 }
20 19
21 func (c *RpcCommand) Info() *cmd.Info { 20 func (c *RpcCommand) Info() *cmd.Info {
22 » return &cmd.Info{"magic", "", "do magic", "blah doc"} 21 » return &cmd.Info{"remote", "", "act at a distance", "blah doc"}
23 } 22 }
24 23
25 func (c *RpcCommand) Init(f *gnuflag.FlagSet, args []string) error { 24 func (c *RpcCommand) Init(f *gnuflag.FlagSet, args []string) error {
26 f.StringVar(&c.Value, "value", "", "doc") 25 f.StringVar(&c.Value, "value", "", "doc")
27 if err := f.Parse(true, args); err != nil { 26 if err := f.Parse(true, args); err != nil {
28 return err 27 return err
29 } 28 }
30 return cmd.CheckEmpty(f.Args()) 29 return cmd.CheckEmpty(f.Args())
31 } 30 }
32 31
33 func (c *RpcCommand) Run(ctx *cmd.Context) error { 32 func (c *RpcCommand) Run(ctx *cmd.Context) error {
34 » if c.Value != "zyxxy" { 33 » if c.Value == "error" {
35 » » return errors.New("insufficiently magic") 34 » » return errors.New("blam")
36 } 35 }
37 ctx.Stdout.Write([]byte("eye of newt\n")) 36 ctx.Stdout.Write([]byte("eye of newt\n"))
38 ctx.Stderr.Write([]byte("toe of frog\n")) 37 ctx.Stderr.Write([]byte("toe of frog\n"))
39 » return ioutil.WriteFile(ctx.AbsPath("local"), []byte{}, 0644) 38 » return ioutil.WriteFile(ctx.AbsPath("local"), []byte(c.Value), 0644)
40 } 39 }
41 40
42 func factory(contextId, cmdName string) (cmd.Command, error) { 41 func factory(contextId, cmdName string) (cmd.Command, error) {
43 » if contextId != "merlin" { 42 » if contextId != "validCtx" {
44 » » return nil, errors.New("unknown client") 43 » » return nil, fmt.Errorf("unknown context %q", contextId)
45 } 44 }
46 » if cmdName != "magic" { 45 » if cmdName != "remote" {
47 return nil, fmt.Errorf("unknown command %q", cmdName) 46 return nil, fmt.Errorf("unknown command %q", cmdName)
48 } 47 }
49 return &RpcCommand{}, nil 48 return &RpcCommand{}, nil
50 } 49 }
51 50
52 type ServerSuite struct { 51 type ServerSuite struct {
53 server *server.Server 52 server *server.Server
54 sockPath string 53 sockPath string
55 err chan error 54 err chan error
56 } 55 }
(...skipping 21 matching lines...) Expand all
78 client, err := rpc.Dial("unix", s.sockPath) 77 client, err := rpc.Dial("unix", s.sockPath)
79 c.Assert(err, IsNil) 78 c.Assert(err, IsNil)
80 defer client.Close() 79 defer client.Close()
81 err = client.Call("Jujuc.Main", req, &resp) 80 err = client.Call("Jujuc.Main", req, &resp)
82 return resp, err 81 return resp, err
83 } 82 }
84 83
85 func (s *ServerSuite) TestHappyPath(c *C) { 84 func (s *ServerSuite) TestHappyPath(c *C) {
86 dir := c.MkDir() 85 dir := c.MkDir()
87 resp, err := s.Call(c, server.Request{ 86 resp, err := s.Call(c, server.Request{
88 » » "merlin", dir, "magic", []string{"--value", "zyxxy"}}) 87 » » "validCtx", dir, "remote", []string{"--value", "something"}})
89 c.Assert(err, IsNil) 88 c.Assert(err, IsNil)
90 c.Assert(resp.Code, Equals, 0) 89 c.Assert(resp.Code, Equals, 0)
91 c.Assert(string(resp.Stdout), Equals, "eye of newt\n") 90 c.Assert(string(resp.Stdout), Equals, "eye of newt\n")
92 c.Assert(string(resp.Stderr), Equals, "toe of frog\n") 91 c.Assert(string(resp.Stderr), Equals, "toe of frog\n")
93 » _, err = os.Stat(filepath.Join(dir, "local")) 92 » content, err := ioutil.ReadFile(filepath.Join(dir, "local"))
94 c.Assert(err, IsNil) 93 c.Assert(err, IsNil)
94 c.Assert(string(content), Equals, "something")
95 } 95 }
96 96
97 func (s *ServerSuite) TestBadCommandName(c *C) { 97 func (s *ServerSuite) TestBadCommandName(c *C) {
98 dir := c.MkDir() 98 dir := c.MkDir()
99 » _, err := s.Call(c, server.Request{"merlin", dir, "", nil}) 99 » _, err := s.Call(c, server.Request{"validCtx", dir, "", nil})
100 c.Assert(err, ErrorMatches, "bad request: command not specified") 100 c.Assert(err, ErrorMatches, "bad request: command not specified")
101 » _, err = s.Call(c, server.Request{"merlin", dir, "witchcraft", nil}) 101 » _, err = s.Call(c, server.Request{"validCtx", dir, "witchcraft", nil})
102 c.Assert(err, ErrorMatches, `bad request: unknown command "witchcraft"`) 102 c.Assert(err, ErrorMatches, `bad request: unknown command "witchcraft"`)
103 } 103 }
104 104
105 func (s *ServerSuite) TestBadDir(c *C) { 105 func (s *ServerSuite) TestBadDir(c *C) {
106 for _, req := range []server.Request{ 106 for _, req := range []server.Request{
107 » » {"merlin", "", "cmd", nil}, 107 » » {"validCtx", "", "anything", nil},
108 » » {"merlin", "foo/bar", "cmd", nil}, 108 » » {"validCtx", "foo/bar", "anything", nil},
109 } { 109 } {
110 _, err := s.Call(c, req) 110 _, err := s.Call(c, req)
111 c.Assert(err, ErrorMatches, "bad request: Dir is not absolute") 111 c.Assert(err, ErrorMatches, "bad request: Dir is not absolute")
112 } 112 }
113 } 113 }
114 114
115 func (s *ServerSuite) TestBadContextId(c *C) { 115 func (s *ServerSuite) TestBadContextId(c *C) {
116 » _, err := s.Call(c, server.Request{"mordred", c.MkDir(), "magic", nil}) 116 » _, err := s.Call(c, server.Request{"whatever", c.MkDir(), "remote", nil} )
117 » c.Assert(err, ErrorMatches, "bad request: unknown client") 117 » c.Assert(err, ErrorMatches, `bad request: unknown context "whatever"`)
118 } 118 }
119 119
120 func (s *ServerSuite) AssertBadCommand(c *C, args []string, code int) server.Res ponse { 120 func (s *ServerSuite) AssertBadCommand(c *C, args []string, code int) server.Res ponse {
121 » resp, err := s.Call(c, server.Request{"merlin", c.MkDir(), args[0], args [1:]}) 121 » resp, err := s.Call(c, server.Request{"validCtx", c.MkDir(), args[0], ar gs[1:]})
122 c.Assert(err, IsNil) 122 c.Assert(err, IsNil)
123 c.Assert(resp.Code, Equals, code) 123 c.Assert(resp.Code, Equals, code)
124 return resp 124 return resp
125 } 125 }
126 126
127 func lines(b []byte) []string {
128 return strings.Split(string(b), "\n")
129 }
130
131 func (s *ServerSuite) TestParseError(c *C) { 127 func (s *ServerSuite) TestParseError(c *C) {
132 » resp := s.AssertBadCommand(c, []string{"magic", "--cheese"}, 2) 128 » resp := s.AssertBadCommand(c, []string{"remote", "--cheese"}, 2)
133 c.Assert(string(resp.Stdout), Equals, "") 129 c.Assert(string(resp.Stdout), Equals, "")
134 » c.Assert(string(resp.Stderr), Equals, `usage: magic [options] 130 » c.Assert(string(resp.Stderr), Equals, `usage: remote [options]
135 purpose: do magic 131 purpose: act at a distance
136 132
137 options: 133 options:
138 --value (= "") 134 --value (= "")
139 doc 135 doc
140 136
141 blah doc 137 blah doc
142 error: flag provided but not defined: --cheese 138 error: flag provided but not defined: --cheese
143 `) 139 `)
144 } 140 }
145 141
146 func (s *ServerSuite) TestBrokenCommand(c *C) { 142 func (s *ServerSuite) TestBrokenCommand(c *C) {
147 » resp := s.AssertBadCommand(c, []string{"magic"}, 1) 143 » resp := s.AssertBadCommand(c, []string{"remote", "--value", "error"}, 1)
148 c.Assert(string(resp.Stdout), Equals, "") 144 c.Assert(string(resp.Stdout), Equals, "")
149 » c.Assert(string(resp.Stderr), Equals, "error: insufficiently magic\n") 145 » c.Assert(string(resp.Stderr), Equals, "error: blam\n")
150 } 146 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b