Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 1 | package impl_test |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "os" |
| 6 | "testing" |
| 7 | |
| 8 | mtlib "veyron/services/mounttable/lib" |
| 9 | |
| 10 | "veyron/lib/testutil/blackbox" |
| 11 | "veyron/lib/testutil/security" |
| 12 | "veyron/services/mgmt/lib/exec" |
| 13 | |
| 14 | "veyron2" |
| 15 | "veyron2/ipc" |
| 16 | "veyron2/naming" |
| 17 | "veyron2/rt" |
| 18 | "veyron2/services/mgmt/node" |
| 19 | "veyron2/verror" |
| 20 | "veyron2/vlog" |
| 21 | ) |
| 22 | |
| 23 | // TODO(caprita): I've had to write one too many of these, let's move it to some |
| 24 | // central utility library. |
| 25 | |
| 26 | // setupLocalNamespace sets up a mounttable and sets the local namespace root |
| 27 | // to point to it. Returns a cleanup function. |
| 28 | func setupLocalNamespace(t *testing.T) func() { |
| 29 | server, err := rt.R().NewServer(veyron2.ServesMountTableOpt(true)) |
| 30 | if err != nil { |
| 31 | t.Fatalf("NewServer() failed: %v", err) |
| 32 | } |
| 33 | dispatcher, err := mtlib.NewMountTable("") |
| 34 | if err != nil { |
| 35 | t.Fatalf("NewMountTable() failed: %v", err) |
| 36 | } |
Adam Sadovsky | 5181bdb | 2014-08-13 10:29:11 -0700 | [diff] [blame] | 37 | protocol, hostname := "tcp", "127.0.0.1:0" |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 38 | endpoint, err := server.Listen(protocol, hostname) |
| 39 | if err != nil { |
| 40 | t.Fatalf("Listen(%v, %v) failed: %v", protocol, hostname, err) |
| 41 | } |
| 42 | if err := server.Serve("", dispatcher); err != nil { |
| 43 | t.Fatalf("Serve(%v) failed: %v", dispatcher, err) |
| 44 | } |
| 45 | name := naming.JoinAddressName(endpoint.String(), "") |
| 46 | vlog.VI(1).Infof("Mount table object name: %v", name) |
| 47 | ns := rt.R().Namespace() |
| 48 | // Make the runtime's namespace rooted at the MountTable server started |
| 49 | // above. |
| 50 | ns.SetRoots(name) |
| 51 | return func() { |
| 52 | if err := server.Stop(); err != nil { |
| 53 | t.Fatalf("Stop() failed: %v", err) |
| 54 | } |
| 55 | // The runtime outlives the particular test case that invokes |
| 56 | // setupLocalNamespace. It's good practice to reset the |
| 57 | // runtime's state before the next test uses it. |
| 58 | ns.SetRoots() |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | // TODO(caprita): Move this setup into the blackbox lib. |
| 63 | |
| 64 | // setupChildCommand configures the child to use the right mounttable root |
| 65 | // and identity. It returns a cleanup function. |
| 66 | func setupChildCommand(child *blackbox.Child) func() { |
| 67 | cmd := child.Cmd |
| 68 | for i, root := range rt.R().Namespace().Roots() { |
| 69 | cmd.Env = exec.Setenv(cmd.Env, fmt.Sprintf("NAMESPACE_ROOT%d", i), root) |
| 70 | } |
| 71 | idFile := security.SaveIdentityToFile(security.NewBlessedIdentity(rt.R().Identity(), "test")) |
| 72 | cmd.Env = exec.Setenv(cmd.Env, "VEYRON_IDENTITY", idFile) |
| 73 | return func() { |
| 74 | os.Remove(idFile) |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | func newServer() (ipc.Server, string) { |
| 79 | server, err := rt.R().NewServer() |
| 80 | if err != nil { |
| 81 | vlog.Fatalf("NewServer() failed: %v", err) |
| 82 | } |
Adam Sadovsky | 5181bdb | 2014-08-13 10:29:11 -0700 | [diff] [blame] | 83 | protocol, hostname := "tcp", "127.0.0.1:0" |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 84 | endpoint, err := server.Listen(protocol, hostname) |
| 85 | if err != nil { |
| 86 | vlog.Fatalf("Listen(%v, %v) failed: %v", protocol, hostname, err) |
| 87 | } |
| 88 | return server, endpoint.String() |
| 89 | } |
| 90 | |
| 91 | // resolveExpectError verifies that the given name is not in the mounttable. |
Bogdan Caprita | bce0a63 | 2014-09-03 16:15:26 -0700 | [diff] [blame^] | 92 | func resolveExpectNotFound(t *testing.T, name string) { |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 93 | if results, err := rt.R().Namespace().Resolve(rt.R().NewContext(), name); err == nil { |
Jiri Simsa | 6351ee7 | 2014-08-18 16:44:41 -0700 | [diff] [blame] | 94 | t.Fatalf("Resolve(%v) succeeded with results %v when it was expected to fail", name, results) |
Bogdan Caprita | bce0a63 | 2014-09-03 16:15:26 -0700 | [diff] [blame^] | 95 | } else if expectErr := verror.NotFound; !verror.Is(err, expectErr) { |
| 96 | t.Fatalf("Resolve(%v) failed with error %v, expected error ID %v", err, expectErr) |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 97 | } |
| 98 | } |
| 99 | |
| 100 | // resolve looks up the given name in the mounttable. |
Bogdan Caprita | bce0a63 | 2014-09-03 16:15:26 -0700 | [diff] [blame^] | 101 | func resolve(t *testing.T, name string, replicas int) []string { |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 102 | results, err := rt.R().Namespace().Resolve(rt.R().NewContext(), name) |
| 103 | if err != nil { |
| 104 | t.Fatalf("Resolve(%v) failed: %v", name, err) |
| 105 | } |
Bogdan Caprita | bce0a63 | 2014-09-03 16:15:26 -0700 | [diff] [blame^] | 106 | if want, got := replicas, len(results); want != got { |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 107 | t.Fatalf("Resolve(%v) expected %d result(s), got %d instead", name, want, got) |
| 108 | } |
Bogdan Caprita | bce0a63 | 2014-09-03 16:15:26 -0700 | [diff] [blame^] | 109 | return results |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 110 | } |
| 111 | |
| 112 | // The following set of functions are convenience wrappers around Update and |
| 113 | // Revert. |
| 114 | |
| 115 | func updateExpectError(t *testing.T, name string, errID verror.ID) { |
| 116 | if err := invokeUpdate(t, name); !verror.Is(err, errID) { |
Robert Kroeger | 854860d | 2014-08-28 14:22:05 -0700 | [diff] [blame] | 117 | t.Fatalf("Unexpected update on %s error %v, expected error ID %v", name, err, errID) |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 118 | } |
| 119 | } |
| 120 | |
| 121 | func update(t *testing.T, name string) { |
| 122 | if err := invokeUpdate(t, name); err != nil { |
Robert Kroeger | 854860d | 2014-08-28 14:22:05 -0700 | [diff] [blame] | 123 | t.Fatalf("Update() on %s failed: %v", name, err) |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 124 | } |
| 125 | } |
| 126 | |
| 127 | func invokeUpdate(t *testing.T, name string) error { |
| 128 | address := naming.Join(name, "nm") |
| 129 | stub, err := node.BindNode(address) |
| 130 | if err != nil { |
| 131 | t.Fatalf("BindNode(%v) failed: %v", address, err) |
| 132 | } |
| 133 | return stub.Update(rt.R().NewContext()) |
| 134 | } |
| 135 | |
| 136 | func revertExpectError(t *testing.T, name string, errID verror.ID) { |
| 137 | if err := invokeRevert(t, name); !verror.Is(err, errID) { |
Jiri Simsa | 6351ee7 | 2014-08-18 16:44:41 -0700 | [diff] [blame] | 138 | t.Fatalf("Unexpected revert error %v, expected error ID %v", err, errID) |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 139 | } |
| 140 | } |
| 141 | |
| 142 | func revert(t *testing.T, name string) { |
| 143 | if err := invokeRevert(t, name); err != nil { |
Jiri Simsa | 6351ee7 | 2014-08-18 16:44:41 -0700 | [diff] [blame] | 144 | t.Fatalf("Revert() failed: %v", err) |
Bogdan Caprita | c87a914 | 2014-07-21 10:38:13 -0700 | [diff] [blame] | 145 | } |
| 146 | } |
| 147 | |
| 148 | func invokeRevert(t *testing.T, name string) error { |
| 149 | address := naming.Join(name, "nm") |
| 150 | stub, err := node.BindNode(address) |
| 151 | if err != nil { |
| 152 | t.Fatalf("BindNode(%v) failed: %v", address, err) |
| 153 | } |
| 154 | return stub.Revert(rt.R().NewContext()) |
| 155 | } |