Merge "needed for v.io/c/11752"
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 cddd6dd..7bdb1de 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)