veyron/runtimes/google/naming/namespace: Don't send Finished glob queries to terminal servers.

Change-Id: I4975127a3bcafa0408e99b32f4706520132daf64
diff --git a/runtimes/google/naming/namespace/all_test.go b/runtimes/google/naming/namespace/all_test.go
index 64d6743..17e399e 100644
--- a/runtimes/google/naming/namespace/all_test.go
+++ b/runtimes/google/naming/namespace/all_test.go
@@ -5,6 +5,7 @@
 	"runtime"
 	"runtime/debug"
 	"sort"
+	"sync"
 	"testing"
 	"time"
 
@@ -17,6 +18,7 @@
 	"veyron2/ipc"
 	"veyron2/naming"
 	"veyron2/rt"
+	"veyron2/services/mounttable"
 	"veyron2/vlog"
 )
 
@@ -396,6 +398,60 @@
 	}
 }
 
+type GlobbableServer struct {
+	callCount int
+	mu        sync.Mutex
+}
+
+func (g *GlobbableServer) Glob(ipc.ServerContext, string, mounttable.GlobableServiceGlobStream) error {
+	g.mu.Lock()
+	defer g.mu.Unlock()
+	g.callCount++
+	return nil
+}
+
+func (g *GlobbableServer) GetAndResetCount() int {
+	g.mu.Lock()
+	defer g.mu.Unlock()
+	cnt := g.callCount
+	g.callCount = 0
+
+	return cnt
+}
+
+// TestGlobEarlyStop tests that Glob doesn't query terminal servers with finished patterns.
+func TestGlobEarlyStop(t *testing.T) {
+	sr := rt.Init()
+	r, _ := rt.New() // We use a different runtime for the client side.
+	root, mts, _, stopper := createNamespace(t, sr)
+	runNestedMountTables(t, sr, mts)
+	defer stopper()
+
+	globServer := &GlobbableServer{}
+	name := naming.JoinAddressName(mts["mt4/foo/bar"].name, "glob")
+	runningGlobServer := runServer(t, r, ipc.SoloDispatcher(mounttable.NewServerGlobable(globServer), nil), name)
+	defer runningGlobServer.server.Stop()
+
+	ns := r.Namespace()
+	ns.SetRoots(root.name)
+
+	tests := []struct {
+		pattern       string
+		expectedCalls int
+	}{
+		{"mt4/foo/bar/glob", 0},
+		{"mt4/foo/bar/glob/...", 1},
+		{"mt4/foo/bar/*", 0},
+	}
+	for _, test := range tests {
+		out := doGlob(t, r, ns, test.pattern, 0)
+		compare(t, "Glob", test.pattern, []string{"mt4/foo/bar/glob"}, out)
+		if calls := globServer.GetAndResetCount(); calls != test.expectedCalls {
+			boom(t, "Wrong number of Glob calls to terminal server got: %d want: %d.", calls, test.expectedCalls)
+		}
+	}
+}
+
 func TestCycles(t *testing.T) {
 	sr := rt.Init()
 	r, _ := rt.New() // We use a different runtime for the client side.
diff --git a/runtimes/google/naming/namespace/glob.go b/runtimes/google/naming/namespace/glob.go
index 68d491f..176d8d4 100644
--- a/runtimes/google/naming/namespace/glob.go
+++ b/runtimes/google/naming/namespace/glob.go
@@ -36,6 +36,17 @@
 	var lastErr error
 	// Trying each instance till we get one that works.
 	for _, s := range server.Servers {
+		// If the pattern is finished (so we're only querying about the root on the
+		// remote server) and the server is not another MT, then we needn't send the
+		// query on since we know the server will not supply a new address for the
+		// current name.
+		if pattern.Finished() {
+			_, n := naming.SplitAddressName(s.Server)
+			if strings.HasPrefix(n, "//") {
+				return false, nil
+			}
+		}
+
 		mtServers, err := ns.ResolveToMountTable(ctx, s.Server)
 		if err != nil {
 			lastErr = err