func checkWatchSrvVSchema(t *testing.T, ts topo.Impl) { ctx := context.Background() cell := getLocalCell(ctx, t, ts) emptySrvVSchema := &vschemapb.SrvVSchema{} // start watching, should get nil first ctx, cancel := context.WithCancel(ctx) notifications, err := ts.WatchSrvVSchema(ctx, cell) if err != nil { t.Fatalf("WatchSrvVSchema failed: %v", err) } v, ok := <-notifications if !ok || v != nil { t.Fatalf("first value is wrong: %v %v", v, ok) } // update the SrvVSchema, should get a notification srvVSchema := &vschemapb.SrvVSchema{ Keyspaces: map[string]*vschemapb.Keyspace{ "test_keyspace": { Sharded: true, }, }, } if err := ts.UpdateSrvVSchema(ctx, cell, srvVSchema); err != nil { t.Fatalf("UpdateSrvVSchema failed: %v", err) } for { sk, ok := <-notifications if !ok { t.Fatalf("watch channel is closed???") } if sk == nil { // duplicate notification of the first value, that's OK continue } // non-empty value, that one should be ours if !reflect.DeepEqual(sk, srvVSchema) { t.Fatalf("first value is wrong: got %v expected %v", sk, srvVSchema) } break } // update with an empty value, should get a notification if err := ts.UpdateSrvVSchema(ctx, cell, emptySrvVSchema); err != nil { t.Fatalf("UpdateSrvVSchema failed: %v", err) } for { v, ok := <-notifications if !ok { t.Fatalf("watch channel is closed???") } if v == nil || proto.Equal(v, emptySrvVSchema) { break } // duplicate notification of the first value, that's OK, // but value better be good. if !reflect.DeepEqual(v, srvVSchema) { t.Fatalf("duplicate notification value is bad: %v", v) } } // re-create the value, a bit different, should get a notification srvVSchema.Keyspaces["test_keyspace"].Sharded = false if err := ts.UpdateSrvVSchema(ctx, cell, srvVSchema); err != nil { t.Fatalf("UpdateSrvVSchema failed: %v", err) } for { v, ok := <-notifications if !ok { t.Fatalf("watch channel is closed???") } if v == nil || proto.Equal(v, emptySrvVSchema) { // duplicate notification of the closed value, that's OK continue } // non-empty value, that one should be ours if !reflect.DeepEqual(v, srvVSchema) { t.Fatalf("value after delete / re-create is wrong: %v %v", v, ok) } break } // close the context, should eventually get a closed // notifications channel too cancel() for { v, ok := <-notifications if !ok { break } if !reflect.DeepEqual(v, srvVSchema) { t.Fatalf("duplicate notification value is bad: %v", v) } } }