blob: 37d3cfb2b640257cdc21919951fb558c81254f78 [file] [log] [blame]
Bogdan Capritac87a9142014-07-21 10:38:13 -07001package impl_test
2
3import (
4 "fmt"
5 "os"
6 "testing"
7
Jiri Simsa519c5072014-09-17 21:37:57 -07008 "veyron.io/veyron/veyron2"
9 "veyron.io/veyron/veyron2/ipc"
10 "veyron.io/veyron/veyron2/naming"
11 "veyron.io/veyron/veyron2/rt"
12 "veyron.io/veyron/veyron2/services/mgmt/node"
13 "veyron.io/veyron/veyron2/verror"
14 "veyron.io/veyron/veyron2/vlog"
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070015
Cosmos Nicolaou486d3492014-09-30 22:21:20 -070016 "veyron.io/veyron/veyron/lib/exec"
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070017 "veyron.io/veyron/veyron/lib/testutil/blackbox"
18 "veyron.io/veyron/veyron/lib/testutil/security"
19 "veyron.io/veyron/veyron/profiles"
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070020 mtlib "veyron.io/veyron/veyron/services/mounttable/lib"
Bogdan Capritac87a9142014-07-21 10:38:13 -070021)
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.
28func 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 }
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070037 endpoint, err := server.ListenX(profiles.LocalListenSpec)
Bogdan Capritac87a9142014-07-21 10:38:13 -070038 if err != nil {
Cosmos Nicolaoud6c3c9c2014-09-30 15:42:53 -070039 t.Fatalf("Listen(%s) failed: %v", profiles.LocalListenSpec, err)
Bogdan Capritac87a9142014-07-21 10:38:13 -070040 }
41 if err := server.Serve("", dispatcher); err != nil {
42 t.Fatalf("Serve(%v) failed: %v", dispatcher, err)
43 }
44 name := naming.JoinAddressName(endpoint.String(), "")
45 vlog.VI(1).Infof("Mount table object name: %v", name)
46 ns := rt.R().Namespace()
47 // Make the runtime's namespace rooted at the MountTable server started
48 // above.
49 ns.SetRoots(name)
50 return func() {
51 if err := server.Stop(); err != nil {
52 t.Fatalf("Stop() failed: %v", err)
53 }
54 // The runtime outlives the particular test case that invokes
55 // setupLocalNamespace. It's good practice to reset the
56 // runtime's state before the next test uses it.
57 ns.SetRoots()
58 }
59}
60
61// TODO(caprita): Move this setup into the blackbox lib.
62
63// setupChildCommand configures the child to use the right mounttable root
Asim Shankar88292912014-10-09 19:41:07 -070064// and blessings. It returns a cleanup function.
Bogdan Capritac87a9142014-07-21 10:38:13 -070065func setupChildCommand(child *blackbox.Child) func() {
Bogdan Capritab9501d12014-10-10 15:02:03 -070066 return setupChildCommandWithBlessing(child, "child")
67}
68
69func setupChildCommandWithBlessing(child *blackbox.Child, blessing string) func() {
Bogdan Capritac87a9142014-07-21 10:38:13 -070070 cmd := child.Cmd
71 for i, root := range rt.R().Namespace().Roots() {
72 cmd.Env = exec.Setenv(cmd.Env, fmt.Sprintf("NAMESPACE_ROOT%d", i), root)
73 }
Bogdan Capritab9501d12014-10-10 15:02:03 -070074 childcreds := security.NewVeyronCredentials(rt.R().Principal(), blessing)
Asim Shankar88292912014-10-09 19:41:07 -070075 cmd.Env = exec.Setenv(cmd.Env, "VEYRON_CREDENTIALS", childcreds)
Bogdan Capritac87a9142014-07-21 10:38:13 -070076 return func() {
Asim Shankar88292912014-10-09 19:41:07 -070077 os.RemoveAll(childcreds)
Bogdan Capritac87a9142014-07-21 10:38:13 -070078 }
79}
80
81func newServer() (ipc.Server, string) {
82 server, err := rt.R().NewServer()
83 if err != nil {
84 vlog.Fatalf("NewServer() failed: %v", err)
85 }
Cosmos Nicolaou9348da62014-10-03 14:21:19 -070086 endpoint, err := server.ListenX(profiles.LocalListenSpec)
Bogdan Capritac87a9142014-07-21 10:38:13 -070087 if err != nil {
Cosmos Nicolaou9348da62014-10-03 14:21:19 -070088 vlog.Fatalf("Listen(%s) failed: %v", profiles.LocalListenSpec, err)
Bogdan Capritac87a9142014-07-21 10:38:13 -070089 }
90 return server, endpoint.String()
91}
92
93// resolveExpectError verifies that the given name is not in the mounttable.
Bogdan Capritabce0a632014-09-03 16:15:26 -070094func resolveExpectNotFound(t *testing.T, name string) {
Bogdan Capritac87a9142014-07-21 10:38:13 -070095 if results, err := rt.R().Namespace().Resolve(rt.R().NewContext(), name); err == nil {
Jiri Simsa6351ee72014-08-18 16:44:41 -070096 t.Fatalf("Resolve(%v) succeeded with results %v when it was expected to fail", name, results)
Tilak Sharma492e8e92014-09-18 10:58:14 -070097 } else if expectErr := verror.NoExist; !verror.Is(err, expectErr) {
98 t.Fatalf("Resolve(%v) failed with error %v, expected error ID %v", name, err, expectErr)
Bogdan Capritac87a9142014-07-21 10:38:13 -070099 }
100}
101
102// resolve looks up the given name in the mounttable.
Bogdan Capritabce0a632014-09-03 16:15:26 -0700103func resolve(t *testing.T, name string, replicas int) []string {
Bogdan Capritac87a9142014-07-21 10:38:13 -0700104 results, err := rt.R().Namespace().Resolve(rt.R().NewContext(), name)
105 if err != nil {
106 t.Fatalf("Resolve(%v) failed: %v", name, err)
107 }
Bogdan Capritabce0a632014-09-03 16:15:26 -0700108 if want, got := replicas, len(results); want != got {
Bogdan Capritac87a9142014-07-21 10:38:13 -0700109 t.Fatalf("Resolve(%v) expected %d result(s), got %d instead", name, want, got)
110 }
Bogdan Capritabce0a632014-09-03 16:15:26 -0700111 return results
Bogdan Capritac87a9142014-07-21 10:38:13 -0700112}
113
114// The following set of functions are convenience wrappers around Update and
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700115// Revert for node manager.
Bogdan Capritac87a9142014-07-21 10:38:13 -0700116
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700117func nodeStub(t *testing.T, name string) node.Node {
118 nodeName := naming.Join(name, "nm")
119 stub, err := node.BindNode(nodeName)
Bogdan Capritac87a9142014-07-21 10:38:13 -0700120 if err != nil {
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700121 t.Fatalf("BindNode(%v) failed: %v", nodeName, err)
Bogdan Capritac87a9142014-07-21 10:38:13 -0700122 }
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700123 return stub
Bogdan Capritac87a9142014-07-21 10:38:13 -0700124}
125
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700126func updateNodeExpectError(t *testing.T, name string, errID verror.ID) {
127 if err := nodeStub(t, name).Update(rt.R().NewContext()); !verror.Is(err, errID) {
128 t.Fatalf("Update(%v) expected to fail with %v, got %v instead", name, errID, err)
Bogdan Capritac87a9142014-07-21 10:38:13 -0700129 }
130}
131
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700132func updateNode(t *testing.T, name string) {
133 if err := nodeStub(t, name).Update(rt.R().NewContext()); err != nil {
134 t.Fatalf("Update(%v) failed: %v", name, err)
Bogdan Capritac87a9142014-07-21 10:38:13 -0700135 }
136}
137
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700138func revertNodeExpectError(t *testing.T, name string, errID verror.ID) {
139 if err := nodeStub(t, name).Revert(rt.R().NewContext()); !verror.Is(err, errID) {
140 t.Fatalf("Revert(%v) expected to fail with %v, got %v instead", name, errID, err)
141 }
142}
143
144func revertNode(t *testing.T, name string) {
145 if err := nodeStub(t, name).Revert(rt.R().NewContext()); err != nil {
146 t.Fatalf("Revert(%v) failed: %v", name, err)
147 }
148}
149
150// The following set of functions are convenience wrappers around various app
151// management methods.
152
153func appStub(t *testing.T, nameComponents ...string) node.Application {
154 appsName := "nm//apps"
155 appName := naming.Join(append([]string{appsName}, nameComponents...)...)
156 stub, err := node.BindApplication(appName)
Bogdan Capritac87a9142014-07-21 10:38:13 -0700157 if err != nil {
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700158 t.Fatalf("BindApplication(%v) failed: %v", appName, err)
Bogdan Capritac87a9142014-07-21 10:38:13 -0700159 }
Bogdan Caprita48bbd142014-09-04 16:07:23 -0700160 return stub
161}
162
163func installApp(t *testing.T) string {
164 appID, err := appStub(t).Install(rt.R().NewContext(), "ar")
165 if err != nil {
166 t.Fatalf("Install failed: %v", err)
167 }
168 return appID
169}
170
171func startAppImpl(t *testing.T, appID string) (string, error) {
172 if instanceIDs, err := appStub(t, appID).Start(rt.R().NewContext()); err != nil {
173 return "", err
174 } else {
175 if want, got := 1, len(instanceIDs); want != got {
176 t.Fatalf("Start(%v): expected %v instance ids, got %v instead", appID, want, got)
177 }
178 return instanceIDs[0], nil
179 }
180}
181
182func startApp(t *testing.T, appID string) string {
183 instanceID, err := startAppImpl(t, appID)
184 if err != nil {
185 t.Fatalf("Start(%v) failed: %v", appID, err)
186 }
187 return instanceID
188}
189
190func startAppExpectError(t *testing.T, appID string, expectedError verror.ID) {
191 if _, err := startAppImpl(t, appID); err == nil || !verror.Is(err, expectedError) {
192 t.Fatalf("Start(%v) expected to fail with %v, got %v instead", appID, expectedError, err)
193 }
194}
195
196func stopApp(t *testing.T, appID, instanceID string) {
197 if err := appStub(t, appID, instanceID).Stop(rt.R().NewContext(), 5); err != nil {
198 t.Fatalf("Stop(%v/%v) failed: %v", appID, instanceID, err)
199 }
200}
201
202func suspendApp(t *testing.T, appID, instanceID string) {
203 if err := appStub(t, appID, instanceID).Suspend(rt.R().NewContext()); err != nil {
204 t.Fatalf("Suspend(%v/%v) failed: %v", appID, instanceID, err)
205 }
206}
207
208func resumeApp(t *testing.T, appID, instanceID string) {
209 if err := appStub(t, appID, instanceID).Resume(rt.R().NewContext()); err != nil {
210 t.Fatalf("Resume(%v/%v) failed: %v", appID, instanceID, err)
211 }
212}
213
214func updateApp(t *testing.T, appID string) {
215 if err := appStub(t, appID).Update(rt.R().NewContext()); err != nil {
216 t.Fatalf("Update(%v) failed: %v", appID, err)
217 }
218}
219
220func updateAppExpectError(t *testing.T, appID string, expectedError verror.ID) {
221 if err := appStub(t, appID).Update(rt.R().NewContext()); err == nil || !verror.Is(err, expectedError) {
222 t.Fatalf("Update(%v) expected to fail with %v, got %v instead", appID, expectedError, err)
223 }
224}
225
226func revertApp(t *testing.T, appID string) {
227 if err := appStub(t, appID).Revert(rt.R().NewContext()); err != nil {
228 t.Fatalf("Revert(%v) failed: %v", appID, err)
229 }
230}
231
232func revertAppExpectError(t *testing.T, appID string, expectedError verror.ID) {
233 if err := appStub(t, appID).Revert(rt.R().NewContext()); err == nil || !verror.Is(err, expectedError) {
234 t.Fatalf("Revert(%v) expected to fail with %v, got %v instead", appID, expectedError, err)
235 }
236}
237
238func uninstallApp(t *testing.T, appID string) {
239 if err := appStub(t, appID).Uninstall(rt.R().NewContext()); err != nil {
240 t.Fatalf("Uninstall(%v) failed: %v", appID, err)
241 }
Bogdan Capritac87a9142014-07-21 10:38:13 -0700242}