TestLeastRequestE2E tests the Least Request LB policy in an e2e style. The Least Request balancer is configured as the top level balancer of the channel, and is passed three addresses. Eventually, the test creates three streams, which should be on certain backends according to the least request algo
(t *testing.T)
| 204 | // algorithm. The randomness in the picker is injected in the test to be |
| 205 | // deterministic, allowing the test to make assertions on the distribution. |
| 206 | func (s) TestLeastRequestE2E(t *testing.T) { |
| 207 | defer func(u func() uint32) { |
| 208 | randuint32 = u |
| 209 | }(randuint32) |
| 210 | var index int |
| 211 | indexes := []uint32{ |
| 212 | 0, 0, 1, 1, 2, 2, // Triggers a round robin distribution. |
| 213 | } |
| 214 | randuint32 = func() uint32 { |
| 215 | ret := indexes[index%len(indexes)] |
| 216 | index++ |
| 217 | return ret |
| 218 | } |
| 219 | addresses := setupBackends(t, 3) |
| 220 | |
| 221 | mr := manual.NewBuilderWithScheme("lr-e2e") |
| 222 | defer mr.Close() |
| 223 | |
| 224 | // Configure least request as top level balancer of channel. |
| 225 | lrscJSON := ` |
| 226 | { |
| 227 | "loadBalancingConfig": [ |
| 228 | { |
| 229 | "least_request_experimental": { |
| 230 | "choiceCount": 2 |
| 231 | } |
| 232 | } |
| 233 | ] |
| 234 | }` |
| 235 | sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(lrscJSON) |
| 236 | firstThreeAddresses := []resolver.Address{ |
| 237 | {Addr: addresses[0]}, |
| 238 | {Addr: addresses[1]}, |
| 239 | {Addr: addresses[2]}, |
| 240 | } |
| 241 | mr.InitialState(resolver.State{ |
| 242 | Addresses: firstThreeAddresses, |
| 243 | ServiceConfig: sc, |
| 244 | }) |
| 245 | |
| 246 | cc, err := grpc.NewClient(mr.Scheme()+":///", grpc.WithResolvers(mr), grpc.WithTransportCredentials(insecure.NewCredentials())) |
| 247 | if err != nil { |
| 248 | t.Fatalf("grpc.NewClient() failed: %v", err) |
| 249 | } |
| 250 | defer cc.Close() |
| 251 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 252 | defer cancel() |
| 253 | testServiceClient := testgrpc.NewTestServiceClient(cc) |
| 254 | |
| 255 | // Wait for all 3 backends to round robin across. The happens because a |
| 256 | // SubConn transitioning into READY causes a new picker update. Once the |
| 257 | // picker update with all 3 backends is present, this test can start to make |
| 258 | // assertions based on those backends. |
| 259 | if err := checkRoundRobinRPCs(ctx, testServiceClient, firstThreeAddresses); err != nil { |
| 260 | t.Fatalf("error in expected round robin: %v", err) |
| 261 | } |
| 262 | |
| 263 | // Map ordering of READY SubConns is non deterministic. Thus, perform 3 RPCs |
nothing calls this directly
no test coverage detected