// CheckWatchEndPoints makes sure WatchEndPoints works as expected func CheckWatchEndPoints(ctx context.Context, t *testing.T, ts topo.Server) { cell := getLocalCell(ctx, t, ts) keyspace := "test_keyspace" shard := "-10" tabletType := topo.TYPE_MASTER // start watching, should get nil first notifications, stopWatching, err := ts.WatchEndPoints(ctx, cell, keyspace, shard, tabletType) if err != nil { t.Fatalf("WatchEndPoints failed: %v", err) } ep, ok := <-notifications if !ok || ep != nil { t.Fatalf("first value is wrong: %v %v", ep, ok) } // update the endpoints, should get a notification endPoints := &pb.EndPoints{ Entries: []*pb.EndPoint{ &pb.EndPoint{ Uid: 1, Host: "host1", PortMap: map[string]int32{ "vt": 1234, "mysql": 1235, "grpc": 1236, }, }, }, } if err := topo.UpdateEndPoints(ctx, ts, cell, keyspace, shard, tabletType, endPoints, -1); err != nil { t.Fatalf("UpdateEndPoints failed: %v", err) } for { ep, ok := <-notifications if !ok { t.Fatalf("watch channel is closed???") } if ep == nil { // duplicate notification of the first value, that's OK continue } // non-empty value, that one should be ours if !reflect.DeepEqual(endPoints, ep) { t.Fatalf("first value is wrong: %v %v", ep, ok) } break } // delete the endpoints, should get a notification if err := ts.DeleteEndPoints(ctx, cell, keyspace, shard, tabletType, -1); err != nil { t.Fatalf("DeleteEndPoints failed: %v", err) } for { ep, ok := <-notifications if !ok { t.Fatalf("watch channel is closed???") } if ep == nil { break } // duplicate notification of the first value, that's OK, // but value better be good. if !reflect.DeepEqual(endPoints, ep) { t.Fatalf("duplicate notification value is bad: %v", ep) } } // re-create the value, a bit different, should get a notification endPoints.Entries[0].Uid = 2 if err := topo.UpdateEndPoints(ctx, ts, cell, keyspace, shard, tabletType, endPoints, -1); err != nil { t.Fatalf("UpdateEndPoints failed: %v", err) } for { ep, ok := <-notifications if !ok { t.Fatalf("watch channel is closed???") } if ep == nil { // duplicate notification of the closed value, that's OK continue } // non-empty value, that one should be ours if !reflect.DeepEqual(endPoints, ep) { t.Fatalf("value after delete / re-create is wrong: %v %v", ep, ok) } break } // close the stopWatching channel, should eventually get a closed // notifications channel too close(stopWatching) for { ep, ok := <-notifications if !ok { break } if !reflect.DeepEqual(endPoints, ep) { t.Fatalf("duplicate notification value is bad: %v", ep) } } }