| package rt_test |
| |
| import ( |
| "fmt" |
| "reflect" |
| "sort" |
| "testing" |
| "time" |
| |
| _ "veyron/lib/testutil" |
| isecurity "veyron/runtimes/google/security" |
| vsecurity "veyron/security" |
| |
| "veyron2" |
| "veyron2/ipc" |
| "veyron2/naming" |
| "veyron2/rt" |
| "veyron2/security" |
| ) |
| |
| type testService struct{} |
| |
| func (*testService) EchoIDs(call ipc.ServerCall) (server, client []string) { |
| return call.LocalID().Names(), call.RemoteID().Names() |
| } |
| |
| type S []string |
| |
| func newID(name string) security.PrivateID { |
| id, err := isecurity.NewPrivateID(name, nil) |
| if err != nil { |
| panic(err) |
| } |
| return id |
| } |
| |
| func bless(blessor security.PrivateID, blessee security.PublicID, name string) security.PublicID { |
| blessedID, err := blessor.Bless(blessee, name, 5*time.Minute, nil) |
| if err != nil { |
| panic(err) |
| } |
| return blessedID |
| } |
| |
| func add(store security.PublicIDStore, id security.PublicID, pattern security.PrincipalPattern) { |
| if err := store.Add(id, pattern); err != nil { |
| panic(err) |
| } |
| } |
| |
| func call(r veyron2.Runtime, client ipc.Client, name string) (clientNames, serverNames []string, err error) { |
| c, err := client.StartCall(r.NewContext(), name, "EchoIDs", nil) |
| if err != nil { |
| return nil, nil, err |
| } |
| if err := c.Finish(&serverNames, &clientNames); err != nil { |
| return nil, nil, err |
| } |
| sort.Strings(clientNames) |
| sort.Strings(serverNames) |
| return |
| } |
| |
| func TestClientServerIDs(t *testing.T) { |
| stopServer := func(server ipc.Server) { |
| if err := server.Stop(); err != nil { |
| t.Fatalf("server.Stop failed: %s", err) |
| } |
| } |
| var ( |
| self = newID("self") |
| google = newID("google") |
| veyron = newID("veyron") |
| |
| googleGmailService = bless(google, self.PublicID(), "gmail") |
| googleYoutubeService = bless(google, self.PublicID(), "youtube") |
| veyronService = bless(veyron, self.PublicID(), "service") |
| googleGmailClient = bless(google, self.PublicID(), "gmailClient") |
| googleYoutubeClient = bless(google, self.PublicID(), "youtubeClient") |
| veyronClient = bless(veyron, self.PublicID(), "client") |
| ) |
| isecurity.TrustIdentityProviders(google) |
| isecurity.TrustIdentityProviders(veyron) |
| |
| serverR, err := rt.New(veyron2.RuntimeID(self)) |
| if err != nil { |
| t.Fatalf("rt.New() failed: %s", err) |
| } |
| clientR, err := rt.New(veyron2.RuntimeID(self)) |
| if err != nil { |
| t.Fatalf("rt.New() failed: %s", err) |
| } |
| |
| // Add PublicIDs for running "google/gmail" and "google/youtube" services to |
| // serverR's PublicIDStore. Since these PublicIDs are meant to be by |
| // servers only they are tagged with "". |
| add(serverR.PublicIDStore(), googleGmailService, "") |
| add(serverR.PublicIDStore(), googleYoutubeService, "") |
| // Add PublicIDs for communicating the "google/gmail" and "google/youtube" services |
| // to the clientR's PublicIDStore. |
| add(clientR.PublicIDStore(), googleGmailClient, "google/*") |
| add(clientR.PublicIDStore(), googleYoutubeClient, "google/youtube") |
| |
| type testcase struct { |
| server, client security.PublicID |
| defaultPattern security.PrincipalPattern |
| wantServerNames, wantClientNames []string |
| } |
| tests := []testcase{ |
| { |
| defaultPattern: security.AllPrincipals, |
| wantServerNames: S{"self", "google/gmail", "google/youtube"}, |
| wantClientNames: S{"self", "google/gmailClient", "google/youtubeClient"}, |
| }, |
| { |
| defaultPattern: "google/gmail", |
| wantServerNames: S{"google/gmail"}, |
| wantClientNames: S{"self", "google/gmailClient"}, |
| }, |
| { |
| defaultPattern: "google/youtube", |
| wantServerNames: S{"google/youtube"}, |
| wantClientNames: S{"self", "google/gmailClient", "google/youtubeClient"}, |
| }, |
| { |
| server: veyronService, |
| defaultPattern: security.AllPrincipals, |
| wantServerNames: S{"veyron/service"}, |
| wantClientNames: S{"self"}, |
| }, |
| { |
| client: veyronClient, |
| defaultPattern: security.AllPrincipals, |
| wantServerNames: S{"self", "google/gmail", "google/youtube"}, |
| wantClientNames: S{"veyron/client"}, |
| }, |
| { |
| server: veyronService, |
| client: veyronClient, |
| defaultPattern: security.AllPrincipals, |
| wantServerNames: S{"veyron/service"}, |
| wantClientNames: S{"veyron/client"}, |
| }, |
| } |
| name := func(t testcase) string { |
| return fmt.Sprintf("TestCase{clientPublicIDStore: %v, serverPublicIDStore: %v, client option: %v, server option: %v}", clientR.PublicIDStore(), serverR.PublicIDStore(), t.client, t.server) |
| } |
| for _, test := range tests { |
| if err := serverR.PublicIDStore().SetDefaultPrincipalPattern(test.defaultPattern); err != nil { |
| t.Errorf("serverR.PublicIDStore.SetDefaultPrincipalPattern failed: %s", err) |
| continue |
| } |
| server, err := serverR.NewServer(veyron2.LocalID(test.server)) |
| if err != nil { |
| t.Errorf("serverR.NewServer(...) failed: %s", err) |
| continue |
| } |
| endpoint, err := server.Listen("tcp", "127.0.0.1:0") |
| if err != nil { |
| t.Errorf("error listening to service: ", err) |
| continue |
| } |
| defer stopServer(server) |
| if err := server.Serve("", ipc.LeafDispatcher(&testService{}, |
| vsecurity.NewACLAuthorizer(vsecurity.NewWhitelistACL( |
| map[security.PrincipalPattern]security.LabelSet{ |
| security.AllPrincipals: security.AllLabels, |
| })))); err != nil { |
| t.Errorf("error serving service: ", err) |
| continue |
| } |
| |
| client, err := clientR.NewClient(veyron2.LocalID(test.client)) |
| if err != nil { |
| t.Errorf("clientR.NewClient(...) failed: %s", err) |
| continue |
| } |
| defer client.Close() |
| |
| clientNames, serverNames, err := call(clientR, client, naming.JoinAddressName(fmt.Sprintf("%v", endpoint), "")) |
| if err != nil { |
| t.Errorf("IPC failed: %s", err) |
| continue |
| } |
| sort.Strings(test.wantClientNames) |
| sort.Strings(test.wantServerNames) |
| if !reflect.DeepEqual(clientNames, test.wantClientNames) { |
| t.Errorf("TestCase: %s, Got clientNames: %v, want: %v", name(test), clientNames, test.wantClientNames) |
| continue |
| } |
| if !reflect.DeepEqual(serverNames, test.wantServerNames) { |
| t.Errorf("TestCase: %s, Got serverNames: %v, want: %v", name(test), serverNames, test.wantServerNames) |
| continue |
| } |
| } |
| } |