needed for v.io/c/11752

- 11752 fixes the underlying name publisher to be asynchronous as
  per the original intent. This requires tests that probe for the
  presence of names in the mount table to retry.

MultiPart: 2/2

Change-Id: I746952cfbeb50b558347d0b772fbeabe7a5756ac
diff --git a/clients/shell/go/src/v.io/x/chat/channel_test.go b/clients/shell/go/src/v.io/x/chat/channel_test.go
index 84bd900..6d20fd7 100644
--- a/clients/shell/go/src/v.io/x/chat/channel_test.go
+++ b/clients/shell/go/src/v.io/x/chat/channel_test.go
@@ -13,6 +13,7 @@
 	"v.io/v23"
 	"v.io/v23/context"
 	"v.io/v23/options"
+
 	"v.io/x/ref/services/mounttable/mounttablelib"
 	"v.io/x/ref/test"
 	"v.io/x/ref/test/modules"
@@ -70,14 +71,34 @@
 }
 
 // Asserts that the channel contains members with expected names and no others.
-func AssertMembersWithNames(channel *channel, expectedNames []string) error {
-	members, err := channel.getMembers()
+func AssertMembersWithNames(channel *channel, expectedNames []string, retry bool) error {
+
+	waitForN := func(expected int) ([]*member, error) {
+		deadline := time.Now().Add(5 * time.Minute)
+		for {
+			members, err := channel.getMembers()
+			if err != nil || len(members) != expected {
+				if retry {
+					if time.Now().After(deadline) {
+						return nil, fmt.Errorf("timed out expecting %d members", expected)
+					}
+					time.Sleep(10 * time.Millisecond)
+					continue
+				}
+				if err != nil {
+					return nil, fmt.Errorf("channel.getMembers() failed: %v", err)
+				}
+				return nil, fmt.Errorf("Wrong number of members.  Expected %v, actual %v.", len(members), expected)
+			}
+			return members, nil
+		}
+	}
+
+	members, err := waitForN(len(expectedNames))
 	if err != nil {
-		return fmt.Errorf("channel.getMembers() failed: %v", err)
+		return err
 	}
-	if actualLen, expectedLen := len(members), len(expectedNames); actualLen != expectedLen {
-		return fmt.Errorf("Wrong number of members.  Expected %v, actual %v.", expectedLen, actualLen)
-	}
+
 	for _, expectedName := range expectedNames {
 		found := false
 		for _, member := range members {
@@ -107,11 +128,11 @@
 	// Create a new channel.
 	channel, err := newChannel(ctx, mounttable, proxy, path)
 	if err != nil {
-		t.Fatalf("newChannel(%v, %v, %v, %v) failed: %v", ctx, mounttable, proxy, path, err)
+		t.Fatalf("newChannel(%v, %v, %v) failed: %v", mounttable, proxy, path, err)
 	}
 
 	// New channel should be empty.
-	if err := AssertMembersWithNames(channel, []string{}); err != nil {
+	if err := AssertMembersWithNames(channel, []string{}, false); err != nil {
 		t.Error(err)
 	}
 
@@ -121,21 +142,21 @@
 	}
 
 	// Channel should contain only current user.
-	if err := AssertMembersWithNames(channel, []string{channel.UserName()}); err != nil {
+	if err := AssertMembersWithNames(channel, []string{channel.UserName()}, true); err != nil {
 		t.Error(err)
 	}
 
 	// Create and join the channel a second time.
 	channel2, err := newChannel(ctx, mounttable, proxy, path)
 	if err != nil {
-		t.Fatalf("newChannel(%v, %v, %v, %v) failed: %v", ctx, mounttable, proxy, path, err)
+		t.Fatalf("newChannel(%v, %v, %v) failed: %v", mounttable, proxy, path, err)
 	}
 	if err := channel2.join(); err != nil {
 		t.Fatalf("channel2.join() failed: %v", err)
 	}
 
 	// Channel should contain both users.
-	if err := AssertMembersWithNames(channel, []string{channel.UserName(), channel2.UserName()}); err != nil {
+	if err := AssertMembersWithNames(channel, []string{channel.UserName(), channel2.UserName()}, true); err != nil {
 		t.Error(err)
 	}
 
@@ -145,7 +166,7 @@
 	}
 
 	// Channel should contain only second user.
-	if err := AssertMembersWithNames(channel, []string{channel2.UserName()}); err != nil {
+	if err := AssertMembersWithNames(channel, []string{channel2.UserName()}, true); err != nil {
 		t.Error(err)
 	}
 
@@ -155,7 +176,7 @@
 	}
 
 	// Channel should be empty.
-	if err := AssertMembersWithNames(channel, []string{}); err != nil {
+	if err := AssertMembersWithNames(channel, []string{}, true); err != nil {
 		t.Error(err)
 	}
 }
@@ -173,7 +194,7 @@
 
 	channel, err := newChannel(ctx, mounttable, proxy, path)
 	if err != nil {
-		t.Fatalf("newChannel(%v, %v, %v, %v) failed: %v", ctx, mounttable, proxy, path, err)
+		t.Fatalf("newChannel(%v, %v, %v) failed: %v", mounttable, proxy, path, err)
 	}
 
 	defer channel.leave()
@@ -187,8 +208,19 @@
 	go func() {
 		// Call getMembers(), which will set channel.members, used by
 		// channel.broadcastMessage().
-		if _, err := channel.getMembers(); err != nil {
-			t.Fatalf("channel.getMembers() failed: %v", err)
+		deadline := time.Now().Add(time.Minute)
+		for {
+			m, err := channel.getMembers()
+			if err != nil {
+				t.Fatalf("channel.getMembers() failed: %v", err)
+			}
+			if len(m) > 0 {
+				break
+			}
+			if time.Now().After(deadline) {
+				t.Fatalf("channel.getMembers: timed out getting a member")
+			}
+			time.Sleep(10 * time.Millisecond)
 		}
 		if err := channel.broadcastMessage(message); err != nil {
 			t.Fatalf("channel.broadcastMessage(%v) failed: %v", message, err)