TestThreeBackendsAffinity covers that there are 3 SubConns, RPCs with the same hash always pick the same SubConn. Then try different hash to pick another backend, and verify the first hash still picks the first backend.
(t *testing.T)
| 332 | // same hash always pick the same SubConn. Then try different hash to pick |
| 333 | // another backend, and verify the first hash still picks the first backend. |
| 334 | func (s) TestThreeBackendsAffinityMultiple(t *testing.T) { |
| 335 | wantEndpoints := []resolver.Endpoint{ |
| 336 | {Addresses: []resolver.Address{{Addr: testBackendAddrStrs[0]}}}, |
| 337 | {Addresses: []resolver.Address{{Addr: testBackendAddrStrs[1]}}}, |
| 338 | {Addresses: []resolver.Address{{Addr: testBackendAddrStrs[2]}}}, |
| 339 | } |
| 340 | cc, _, p0 := setupTest(t, wantEndpoints) |
| 341 | // This test doesn't update addresses, so this ring will be used by all the |
| 342 | // pickers. |
| 343 | ring0 := p0.(*picker).ring |
| 344 | |
| 345 | firstHash := ring0.items[0].hash |
| 346 | // firstHash+1 will pick the second SubConn from the ring. |
| 347 | testHash := firstHash + 1 |
| 348 | // The first pick should be queued, and should trigger Connect() on the only |
| 349 | // SubConn. |
| 350 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 351 | defer cancel() |
| 352 | if _, err := p0.Pick(balancer.PickInfo{Ctx: iringhash.SetXDSRequestHash(ctx, testHash)}); err != balancer.ErrNoSubConnAvailable { |
| 353 | t.Fatalf("first pick returned err %v, want %v", err, balancer.ErrNoSubConnAvailable) |
| 354 | } |
| 355 | // The picked SubConn should be the second in the ring. |
| 356 | var sc0 *testutils.TestSubConn |
| 357 | select { |
| 358 | case <-ctx.Done(): |
| 359 | t.Fatalf("Timed out waiting for SubConn creation.") |
| 360 | case sc0 = <-cc.NewSubConnCh: |
| 361 | } |
| 362 | if got, want := sc0.Addresses[0].Addr, ring0.items[1].hashKey; got != want { |
| 363 | t.Fatalf("SubConn.Address = %v, want = %v", got, want) |
| 364 | } |
| 365 | select { |
| 366 | case <-sc0.ConnectCh: |
| 367 | case <-time.After(defaultTestTimeout): |
| 368 | t.Errorf("timeout waiting for Connect() from SubConn %v", sc0) |
| 369 | } |
| 370 | |
| 371 | // Send state updates to Ready. |
| 372 | sc0.UpdateState(balancer.SubConnState{ConnectivityState: connectivity.Connecting}) |
| 373 | sc0.UpdateState(balancer.SubConnState{ConnectivityState: connectivity.Ready}) |
| 374 | if err := cc.WaitForConnectivityState(ctx, connectivity.Ready); err != nil { |
| 375 | t.Fatal(err) |
| 376 | } |
| 377 | |
| 378 | // First hash should always pick sc0. |
| 379 | p1 := <-cc.NewPickerCh |
| 380 | for i := 0; i < 5; i++ { |
| 381 | gotSCSt, _ := p1.Pick(balancer.PickInfo{Ctx: iringhash.SetXDSRequestHash(ctx, testHash)}) |
| 382 | if gotSCSt.SubConn != sc0 { |
| 383 | t.Fatalf("picker.Pick, got %v, want SubConn=%v", gotSCSt, sc0) |
| 384 | } |
| 385 | } |
| 386 | |
| 387 | secondHash := ring0.items[1].hash |
| 388 | // secondHash+1 will pick the third SubConn from the ring. |
| 389 | testHash2 := secondHash + 1 |
| 390 | if _, err := p0.Pick(balancer.PickInfo{Ctx: iringhash.SetXDSRequestHash(ctx, testHash2)}); err != balancer.ErrNoSubConnAvailable { |
| 391 | t.Fatalf("first pick returned err %v, want %v", err, balancer.ErrNoSubConnAvailable) |
nothing calls this directly
no test coverage detected