| package unresolve |
| |
| import ( |
| "fmt" |
| "testing" |
| |
| "veyron2" |
| "veyron2/ipc" |
| "veyron2/naming" |
| "veyron2/rt" |
| mtidl "veyron2/services/mounttable" |
| "veyron2/vlog" |
| |
| _ "veyron/lib/testutil" |
| "veyron/lib/testutil/blackbox" |
| mounttable "veyron/services/mounttable/lib" |
| |
| fortuneidl "veyron/examples/fortune" |
| ) |
| |
| func initRT(opts ...veyron2.ROpt) func() { |
| return rt.Init(opts...).Shutdown |
| } |
| |
| func newServer(opts ...ipc.ServerOpt) ipc.Server { |
| server, err := rt.R().NewServer(opts...) |
| if err != nil { |
| panic(fmt.Sprintf("r.NewServer failed with %v", err)) |
| } |
| return server |
| } |
| |
| func createServer(server ipc.Server, prefix string, dispatcher ipc.Dispatcher) string { |
| if err := server.Register(prefix, dispatcher); err != nil { |
| panic(fmt.Sprintf("server.Register failed with %v", err)) |
| } |
| ep, err := server.Listen("tcp", "127.0.0.1:0") |
| if err != nil { |
| panic(fmt.Sprintf("server.Listen failed with %v", err)) |
| } |
| return naming.JoinAddressName(ep.String(), prefix) |
| } |
| |
| func serverMain(servesMT bool, serviceCreator func(ipc.Server) string, args []string) { |
| defer initRT()() |
| server := newServer(veyron2.ServesMountTableOpt(servesMT)) |
| defer server.Stop() |
| service := serviceCreator(server) |
| vlog.Infof("created %v", service) |
| for _, arg := range args { |
| if err := server.Publish(arg); err != nil { |
| panic(fmt.Sprintf("server.Publish(%q) failed with %v", arg, err)) |
| } |
| } |
| fmt.Println("ready") |
| blackbox.WaitForEOFOnStdin() |
| } |
| |
| func createMT(server ipc.Server) string { |
| mt, err := mounttable.NewMountTable("") |
| if err != nil { |
| panic(fmt.Sprintf("NewMountTable failed with %v", err)) |
| } |
| return createServer(server, "mt", mt) |
| } |
| |
| func childMT(args []string) { |
| serverMain(true, createMT, args) |
| } |
| |
| func createMTClient(name string) mtidl.MountTable { |
| client, err := mtidl.BindMountTable(name) |
| if err != nil { |
| panic(fmt.Sprintf("BindMountTable failed with %v", err)) |
| } |
| return client |
| } |
| |
| const fixedFortuneMessage = "Sooner than you think, you will be deeply dissatisfied with a fortune." |
| |
| type fortune struct{} |
| |
| func (*fortune) Get(ipc.ServerContext) (string, error) { |
| return fixedFortuneMessage, nil |
| } |
| |
| func (*fortune) Add(ipc.ServerContext, string) error { |
| return nil |
| } |
| |
| func createFortune(server ipc.Server) string { |
| return createServer(server, "fortune", ipc.SoloDispatcher(fortuneidl.NewServerFortune(new(fortune)), nil)) |
| } |
| |
| func childFortune(args []string) { |
| serverMain(false, createFortune, args) |
| } |
| |
| type fortuneCustomUnresolve struct { |
| custom string |
| } |
| |
| func (*fortuneCustomUnresolve) Get(ipc.ServerContext) (string, error) { |
| return fixedFortuneMessage, nil |
| } |
| |
| func (*fortuneCustomUnresolve) Add(ipc.ServerContext, string) error { |
| return nil |
| } |
| |
| func (*fortuneCustomUnresolve) UnresolveStep(context ipc.ServerContext) ([]string, error) { |
| servers, err := rt.R().MountTable().ResolveToMountTable("I/want/to/know") |
| if err != nil { |
| return nil, err |
| } |
| var reply []string |
| for _, s := range servers { |
| r := naming.MakeResolvable(s) |
| reply = append(reply, naming.Join(r, "the/future")) |
| } |
| return reply, nil |
| } |
| |
| func createFortuneCustomUnresolve(server ipc.Server) string { |
| oa := createServer(server, "tell/me/the/future", ipc.SoloDispatcher(fortuneidl.NewServerFortune(new(fortuneCustomUnresolve)), nil)) |
| ep, _ := naming.SplitAddressName(oa) |
| oa = naming.MakeTerminal(naming.JoinAddressName(ep, "tell/me")) |
| // Doesn't get unmounted. Fine for a test. |
| oa = naming.MakeTerminal(oa) |
| rt.R().MountTable().Mount("I/want/to/know", oa, 0) |
| return oa |
| } |
| |
| func childFortuneCustomUnresolve(args []string) { |
| serverMain(false, createFortuneCustomUnresolve, args) |
| } |
| |
| func createFortuneClient(rt veyron2.Runtime, name string) fortuneidl.Fortune { |
| client, err := fortuneidl.BindFortune(name, veyron2.RuntimeOpt{rt}) |
| if err != nil { |
| panic(fmt.Sprintf("BindFortune failed with %v", err)) |
| } |
| return client |
| } |
| |
| type fortuneNoIDL struct{} |
| |
| func (*fortuneNoIDL) Get(ipc.ServerCall) (string, error) { |
| return fixedFortuneMessage, nil |
| } |
| |
| func (*fortuneNoIDL) UnresolveStep(ipc.ServerCall) ([]string, error) { |
| servers, err := rt.R().MountTable().ResolveToMountTable("g") |
| if err != nil { |
| return nil, err |
| } |
| var reply []string |
| for _, s := range servers { |
| r := naming.MakeResolvable(s) |
| reply = append(reply, naming.Join(r, "fortune")) |
| } |
| return reply, nil |
| } |
| |
| func createFortuneNoIDL(server ipc.Server) string { |
| return createServer(server, "fortune", ipc.SoloDispatcher(new(fortuneNoIDL), nil)) |
| } |
| |
| func childFortuneNoIDL(args []string) { |
| serverMain(false, createFortuneNoIDL, args) |
| } |
| |
| func resolveStep(t *testing.T, name string) string { |
| client := createMTClient(name) |
| results, suffix, err := client.ResolveStep(rt.R().NewContext()) |
| if err != nil { |
| t.Errorf("ResolveStep on %q failed with %v", name, err) |
| return "" |
| } |
| if len(results) != 1 { |
| t.Errorf("Expected one result when resolving %q, got %q", name, results) |
| return "" |
| } |
| return naming.Join(results[0].Server, suffix) |
| } |
| |
| func resolve(t *testing.T, mt naming.MountTable, name string) string { |
| results, err := mt.Resolve(name) |
| if err != nil { |
| t.Errorf("Resolve failed with %v", err) |
| return "" |
| } |
| if len(results) != 1 { |
| t.Errorf("Expected one result when resolving %q, got %q", name, results) |
| return "" |
| } |
| return results[0] |
| } |
| |
| type unresolver interface { |
| UnresolveStep(ipc.Context, ...ipc.CallOpt) ([]string, error) |
| } |
| |
| func unresolveStep(t *testing.T, ctx ipc.Context, c unresolver) string { |
| unres, err := c.UnresolveStep(ctx) |
| if err != nil { |
| t.Errorf("UnresolveStep failed with %v", err) |
| return "" |
| } |
| if len(unres) != 1 { |
| t.Errorf("c.UnresolveStep wanted 1 result, got: %q", unres) |
| return "" |
| } |
| return unres[0] |
| } |
| |
| func unresolve(t *testing.T, mt naming.MountTable, name string) string { |
| results, err := mt.Unresolve(name) |
| if err != nil { |
| t.Errorf("Unresolve failed with %v", err) |
| return "" |
| } |
| if len(results) != 1 { |
| t.Errorf("Expected one result when unresolving %q, got %q", name, results) |
| return "" |
| } |
| return results[0] |
| } |