| package impl_test |
| |
| import ( |
| "fmt" |
| "os" |
| "testing" |
| |
| "veyron.io/veyron/veyron2" |
| "veyron.io/veyron/veyron2/ipc" |
| "veyron.io/veyron/veyron2/naming" |
| "veyron.io/veyron/veyron2/rt" |
| "veyron.io/veyron/veyron2/services/mgmt/node" |
| "veyron.io/veyron/veyron2/verror" |
| "veyron.io/veyron/veyron2/vlog" |
| |
| "veyron.io/veyron/veyron/lib/exec" |
| "veyron.io/veyron/veyron/lib/testutil/blackbox" |
| "veyron.io/veyron/veyron/lib/testutil/security" |
| "veyron.io/veyron/veyron/profiles" |
| mtlib "veyron.io/veyron/veyron/services/mounttable/lib" |
| ) |
| |
| // TODO(caprita): I've had to write one too many of these, let's move it to some |
| // central utility library. |
| |
| // setupLocalNamespace sets up a mounttable and sets the local namespace root |
| // to point to it. Returns a cleanup function. |
| func setupLocalNamespace(t *testing.T) func() { |
| server, err := rt.R().NewServer(veyron2.ServesMountTableOpt(true)) |
| if err != nil { |
| t.Fatalf("NewServer() failed: %v", err) |
| } |
| dispatcher, err := mtlib.NewMountTable("") |
| if err != nil { |
| t.Fatalf("NewMountTable() failed: %v", err) |
| } |
| endpoint, err := server.ListenX(profiles.LocalListenSpec) |
| if err != nil { |
| t.Fatalf("Listen(%s) failed: %v", profiles.LocalListenSpec, err) |
| } |
| if err := server.Serve("", dispatcher); err != nil { |
| t.Fatalf("Serve(%v) failed: %v", dispatcher, err) |
| } |
| name := naming.JoinAddressName(endpoint.String(), "") |
| vlog.VI(1).Infof("Mount table object name: %v", name) |
| ns := rt.R().Namespace() |
| // Make the runtime's namespace rooted at the MountTable server started |
| // above. |
| ns.SetRoots(name) |
| return func() { |
| if err := server.Stop(); err != nil { |
| t.Fatalf("Stop() failed: %v", err) |
| } |
| // The runtime outlives the particular test case that invokes |
| // setupLocalNamespace. It's good practice to reset the |
| // runtime's state before the next test uses it. |
| ns.SetRoots() |
| } |
| } |
| |
| // TODO(caprita): Move this setup into the blackbox lib. |
| |
| // setupChildCommand configures the child to use the right mounttable root |
| // and identity. It returns a cleanup function. |
| func setupChildCommand(child *blackbox.Child) func() { |
| cmd := child.Cmd |
| for i, root := range rt.R().Namespace().Roots() { |
| cmd.Env = exec.Setenv(cmd.Env, fmt.Sprintf("NAMESPACE_ROOT%d", i), root) |
| } |
| idFile := security.SaveIdentityToFile(security.NewBlessedIdentity(rt.R().Identity(), "test")) |
| cmd.Env = exec.Setenv(cmd.Env, "VEYRON_IDENTITY", idFile) |
| return func() { |
| os.Remove(idFile) |
| } |
| } |
| |
| func newServer() (ipc.Server, string) { |
| server, err := rt.R().NewServer() |
| if err != nil { |
| vlog.Fatalf("NewServer() failed: %v", err) |
| } |
| protocol, hostname := "tcp", "127.0.0.1:0" |
| endpoint, err := server.Listen(protocol, hostname) |
| if err != nil { |
| vlog.Fatalf("Listen(%v, %v) failed: %v", protocol, hostname, err) |
| } |
| return server, endpoint.String() |
| } |
| |
| // resolveExpectError verifies that the given name is not in the mounttable. |
| func resolveExpectNotFound(t *testing.T, name string) { |
| if results, err := rt.R().Namespace().Resolve(rt.R().NewContext(), name); err == nil { |
| t.Fatalf("Resolve(%v) succeeded with results %v when it was expected to fail", name, results) |
| } else if expectErr := verror.NoExist; !verror.Is(err, expectErr) { |
| t.Fatalf("Resolve(%v) failed with error %v, expected error ID %v", name, err, expectErr) |
| } |
| } |
| |
| // resolve looks up the given name in the mounttable. |
| func resolve(t *testing.T, name string, replicas int) []string { |
| results, err := rt.R().Namespace().Resolve(rt.R().NewContext(), name) |
| if err != nil { |
| t.Fatalf("Resolve(%v) failed: %v", name, err) |
| } |
| if want, got := replicas, len(results); want != got { |
| t.Fatalf("Resolve(%v) expected %d result(s), got %d instead", name, want, got) |
| } |
| return results |
| } |
| |
| // The following set of functions are convenience wrappers around Update and |
| // Revert for node manager. |
| |
| func nodeStub(t *testing.T, name string) node.Node { |
| nodeName := naming.Join(name, "nm") |
| stub, err := node.BindNode(nodeName) |
| if err != nil { |
| t.Fatalf("BindNode(%v) failed: %v", nodeName, err) |
| } |
| return stub |
| } |
| |
| func updateNodeExpectError(t *testing.T, name string, errID verror.ID) { |
| if err := nodeStub(t, name).Update(rt.R().NewContext()); !verror.Is(err, errID) { |
| t.Fatalf("Update(%v) expected to fail with %v, got %v instead", name, errID, err) |
| } |
| } |
| |
| func updateNode(t *testing.T, name string) { |
| if err := nodeStub(t, name).Update(rt.R().NewContext()); err != nil { |
| t.Fatalf("Update(%v) failed: %v", name, err) |
| } |
| } |
| |
| func revertNodeExpectError(t *testing.T, name string, errID verror.ID) { |
| if err := nodeStub(t, name).Revert(rt.R().NewContext()); !verror.Is(err, errID) { |
| t.Fatalf("Revert(%v) expected to fail with %v, got %v instead", name, errID, err) |
| } |
| } |
| |
| func revertNode(t *testing.T, name string) { |
| if err := nodeStub(t, name).Revert(rt.R().NewContext()); err != nil { |
| t.Fatalf("Revert(%v) failed: %v", name, err) |
| } |
| } |
| |
| // The following set of functions are convenience wrappers around various app |
| // management methods. |
| |
| func appStub(t *testing.T, nameComponents ...string) node.Application { |
| appsName := "nm//apps" |
| appName := naming.Join(append([]string{appsName}, nameComponents...)...) |
| stub, err := node.BindApplication(appName) |
| if err != nil { |
| t.Fatalf("BindApplication(%v) failed: %v", appName, err) |
| } |
| return stub |
| } |
| |
| func installApp(t *testing.T) string { |
| appID, err := appStub(t).Install(rt.R().NewContext(), "ar") |
| if err != nil { |
| t.Fatalf("Install failed: %v", err) |
| } |
| return appID |
| } |
| |
| func startAppImpl(t *testing.T, appID string) (string, error) { |
| if instanceIDs, err := appStub(t, appID).Start(rt.R().NewContext()); err != nil { |
| return "", err |
| } else { |
| if want, got := 1, len(instanceIDs); want != got { |
| t.Fatalf("Start(%v): expected %v instance ids, got %v instead", appID, want, got) |
| } |
| return instanceIDs[0], nil |
| } |
| } |
| |
| func startApp(t *testing.T, appID string) string { |
| instanceID, err := startAppImpl(t, appID) |
| if err != nil { |
| t.Fatalf("Start(%v) failed: %v", appID, err) |
| } |
| return instanceID |
| } |
| |
| func startAppExpectError(t *testing.T, appID string, expectedError verror.ID) { |
| if _, err := startAppImpl(t, appID); err == nil || !verror.Is(err, expectedError) { |
| t.Fatalf("Start(%v) expected to fail with %v, got %v instead", appID, expectedError, err) |
| } |
| } |
| |
| func stopApp(t *testing.T, appID, instanceID string) { |
| if err := appStub(t, appID, instanceID).Stop(rt.R().NewContext(), 5); err != nil { |
| t.Fatalf("Stop(%v/%v) failed: %v", appID, instanceID, err) |
| } |
| } |
| |
| func suspendApp(t *testing.T, appID, instanceID string) { |
| if err := appStub(t, appID, instanceID).Suspend(rt.R().NewContext()); err != nil { |
| t.Fatalf("Suspend(%v/%v) failed: %v", appID, instanceID, err) |
| } |
| } |
| |
| func resumeApp(t *testing.T, appID, instanceID string) { |
| if err := appStub(t, appID, instanceID).Resume(rt.R().NewContext()); err != nil { |
| t.Fatalf("Resume(%v/%v) failed: %v", appID, instanceID, err) |
| } |
| } |
| |
| func updateApp(t *testing.T, appID string) { |
| if err := appStub(t, appID).Update(rt.R().NewContext()); err != nil { |
| t.Fatalf("Update(%v) failed: %v", appID, err) |
| } |
| } |
| |
| func updateAppExpectError(t *testing.T, appID string, expectedError verror.ID) { |
| if err := appStub(t, appID).Update(rt.R().NewContext()); err == nil || !verror.Is(err, expectedError) { |
| t.Fatalf("Update(%v) expected to fail with %v, got %v instead", appID, expectedError, err) |
| } |
| } |
| |
| func revertApp(t *testing.T, appID string) { |
| if err := appStub(t, appID).Revert(rt.R().NewContext()); err != nil { |
| t.Fatalf("Revert(%v) failed: %v", appID, err) |
| } |
| } |
| |
| func revertAppExpectError(t *testing.T, appID string, expectedError verror.ID) { |
| if err := appStub(t, appID).Revert(rt.R().NewContext()); err == nil || !verror.Is(err, expectedError) { |
| t.Fatalf("Revert(%v) expected to fail with %v, got %v instead", appID, expectedError, err) |
| } |
| } |
| |
| func uninstallApp(t *testing.T, appID string) { |
| if err := appStub(t, appID).Uninstall(rt.R().NewContext()); err != nil { |
| t.Fatalf("Uninstall(%v) failed: %v", appID, err) |
| } |
| } |