blob: 94895f2f382ef4290cc4ba80828bfc37f493fb40 [file] [log] [blame]
Jiri Simsa5293dcb2014-05-10 09:56:38 -07001package unresolve
2
3import (
4 "fmt"
5 "testing"
6
7 "veyron2"
8 "veyron2/ipc"
9 "veyron2/naming"
10 "veyron2/rt"
11 mtidl "veyron2/services/mounttable"
12 "veyron2/vlog"
13
14 _ "veyron/lib/testutil"
15 "veyron/lib/testutil/blackbox"
16 mounttable "veyron/services/mounttable/lib"
17
18 fortuneidl "veyron/examples/fortune"
19)
20
21func initRT(opts ...veyron2.ROpt) func() {
22 return rt.Init(opts...).Shutdown
23}
24
25func newServer() ipc.Server {
26 server, err := rt.R().NewServer()
27 if err != nil {
28 panic(fmt.Sprintf("r.NewServer failed with %v", err))
29 }
30 return server
31}
32
33func createServer(server ipc.Server, prefix string, dispatcher ipc.Dispatcher) string {
34 if err := server.Register(prefix, dispatcher); err != nil {
35 panic(fmt.Sprintf("server.Register failed with %v", err))
36 }
37 ep, err := server.Listen("tcp", "127.0.0.1:0")
38 if err != nil {
39 panic(fmt.Sprintf("server.Listen failed with %v", err))
40 }
41 return naming.JoinAddressName(ep.String(), prefix)
42}
43
44func serverMain(serviceCreator func(ipc.Server) string, args []string) {
45 defer initRT()()
46 server := newServer()
47 defer server.Stop()
48 service := serviceCreator(server)
49 vlog.Infof("created %v", service)
50 for _, arg := range args {
51 if err := server.Publish(arg); err != nil {
52 panic(fmt.Sprintf("server.Publish(%q) failed with %v", arg, err))
53 }
54 }
55 fmt.Println("ready")
56 blackbox.WaitForEOFOnStdin()
57}
58
59func createMT(server ipc.Server) string {
60 return createServer(server, "mt", mounttable.NewMountTable())
61}
62
63func childMT(args []string) {
64 serverMain(createMT, args)
65}
66
67func createMTClient(name string) mtidl.MountTable {
68 client, err := mtidl.BindMountTable(name)
69 if err != nil {
70 panic(fmt.Sprintf("BindMountTable failed with %v", err))
71 }
72 return client
73}
74
75const fixedFortuneMessage = "Sooner than you think, you will be deeply dissatisfied with a fortune."
76
77type fortune struct{}
78
79func (*fortune) Get(ipc.Context) (string, error) {
80 return fixedFortuneMessage, nil
81}
82
83func (*fortune) Add(ipc.Context, string) error {
84 return nil
85}
86
87func createFortune(server ipc.Server) string {
88 return createServer(server, "fortune", ipc.SoloDispatcher(fortuneidl.NewServerFortune(new(fortune)), nil))
89}
90
91func childFortune(args []string) {
92 serverMain(createFortune, args)
93}
94
95type fortuneCustomUnresolve struct {
96 custom string
97}
98
99func (*fortuneCustomUnresolve) Get(ipc.Context) (string, error) {
100 return fixedFortuneMessage, nil
101}
102
103func (*fortuneCustomUnresolve) Add(ipc.Context, string) error {
104 return nil
105}
106
107func (*fortuneCustomUnresolve) UnresolveStep(context ipc.Context) ([]string, error) {
108 servers, err := rt.R().MountTable().ResolveToMountTable("I/want/to/know")
109 if err != nil {
110 return nil, err
111 }
112 var reply []string
113 for _, s := range servers {
114 reply = append(reply, naming.Join(naming.MakeNotFixed(s), "the/future"))
115 }
116 return reply, nil
117}
118
119func createFortuneCustomUnresolve(server ipc.Server) string {
120 oa := createServer(server, "tell/me/the/future", ipc.SoloDispatcher(fortuneidl.NewServerFortune(new(fortuneCustomUnresolve)), nil))
121 ep, _ := naming.SplitAddressName(oa)
122 oa = naming.JoinAddressName(ep, "tell/me")
123 // Doesn't get unmounted. Fine for a test.
124 rt.R().MountTable().Mount("I/want/to/know", oa, 0)
125 return oa
126}
127
128func childFortuneCustomUnresolve(args []string) {
129 serverMain(createFortuneCustomUnresolve, args)
130}
131
132func createFortuneClient(rt veyron2.Runtime, name string) fortuneidl.Fortune {
133 client, err := fortuneidl.BindFortune(name, veyron2.RuntimeOpt{rt})
134 if err != nil {
135 panic(fmt.Sprintf("BindFortune failed with %v", err))
136 }
137 return client
138}
139
140type fortuneNoIDL struct{}
141
142func (*fortuneNoIDL) Get(ipc.ServerCall) (string, error) {
143 return fixedFortuneMessage, nil
144}
145
146func (*fortuneNoIDL) UnresolveStep(ipc.ServerCall) ([]string, error) {
147 servers, err := rt.R().MountTable().ResolveToMountTable("g")
148 if err != nil {
149 return nil, err
150 }
151 var reply []string
152 for _, s := range servers {
153 reply = append(reply, naming.Join(naming.MakeNotFixed(s), "fortune"))
154 }
155 return reply, nil
156}
157
158func createFortuneNoIDL(server ipc.Server) string {
159 return createServer(server, "fortune", ipc.SoloDispatcher(new(fortuneNoIDL), nil))
160}
161
162func childFortuneNoIDL(args []string) {
163 serverMain(createFortuneNoIDL, args)
164}
165
166func resolveStep(t *testing.T, name string) string {
167 client := createMTClient(name)
168 results, suffix, err := client.ResolveStep()
169 if err != nil {
170 t.Errorf("ResolveStep on %q failed with %v", name, err)
171 return ""
172 }
173 if len(results) != 1 {
174 t.Errorf("Expected one result when resolving %q, got %q", name, results)
175 return ""
176 }
177 return naming.Join(results[0].Server, suffix)
178}
179
180func resolve(t *testing.T, mt naming.MountTable, name string) string {
181 results, err := mt.Resolve(name)
182 if err != nil {
183 t.Errorf("Resolve failed with %v", err)
184 return ""
185 }
186 if len(results) != 1 {
187 t.Errorf("Expected one result when resolving %q, got %q", name, results)
188 return ""
189 }
190 return results[0]
191}
192
193type unresolver interface {
194 UnresolveStep(...ipc.ClientCallOpt) ([]string, error)
195}
196
197func unresolveStep(t *testing.T, c unresolver) string {
198 unres, err := c.UnresolveStep()
199 if err != nil {
200 t.Errorf("UnresolveStep failed with %v", err)
201 return ""
202 }
203 if len(unres) != 1 {
204 t.Errorf("c.UnresolveStep wanted 1 result, got: %q", unres)
205 return ""
206 }
207 return unres[0]
208}
209
210func unresolve(t *testing.T, mt naming.MountTable, name string) string {
211 results, err := mt.Unresolve(name)
212 if err != nil {
213 t.Errorf("Unresolve failed with %v", err)
214 return ""
215 }
216 if len(results) != 1 {
217 t.Errorf("Expected one result when unresolving %q, got %q", name, results)
218 return ""
219 }
220 return results[0]
221}