Repository: grpc/grpc-go
File: balancer/endpointsharding/endpointsharding_test.go (Go)

Code before:
	sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(json)
	mr.InitialState(resolver.State{
		Endpoints: []resolver.Endpoint{
			{Addresses: []resolver.Address{{Addr: backend1.Address}}},
			{Addresses: []resolver.Address{{Addr: backend2.Address}}},
		},
		ServiceConfig: sc,
	})

	dOpts := []grpc.DialOption{
		grpc.WithResolvers(mr), grpc.WithTransportCredentials(insecure.NewCredentials()),
		// Use a large backoff delay to avoid the error picker being updated
		// too quickly.
		grpc.WithConnectParams(grpc.ConnectParams{
			Backoff: backoff.Config{
				BaseDelay:  2 * defaultTestTimeout,
				Multiplier: float64(0),
				Jitter:     float64(0),
				MaxDelay:   2 * defaultTestTimeout,
			},
		}),
	}
	cc, err := grpc.NewClient(mr.Scheme()+":///", dOpts...)
	if err != nil {
		t.Fatalf("grpc.NewClient() failed: %v", err)
	}
	defer cc.Close()
	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()
	client := testgrpc.NewTestServiceClient(cc)
	// Assert a round robin distribution between the two spun up backends. This
	// requires a poll and eventual consistency as both endpoint children do not
	// start in state READY.
	if err = roundrobin.CheckRoundRobinRPCs(ctx, client, []resolver.Address{{Addr: backend1.Address}, {Addr: backend2.Address}}); err != nil {
		t.Fatalf("error in expected round robin: %v", err)
	}

	// Stopping both the backends should make the channel enter
	// TransientFailure.
	backend1.Stop()
	backend2.Stop()
	testutils.AwaitState(ctx, t, cc, connectivity.TransientFailure)

	// When the resolver reports an error, the picker should get updated to
	// return the resolver error.
	mr.CC().ReportError(errors.New("test error"))
	testutils.AwaitState(ctx, t, cc, connectivity.TransientFailure)
	for ; ctx.Err() == nil; <-time.After(time.Millisecond) {
		_, err := client.EmptyCall(ctx, &testpb.Empty{})
		if err == nil {
			t.Fatalf("EmptyCall succeeded when expected to fail with %q", "test error")

Review comment (suggestion):
Please only change `log` to `t`, the error message is fine.

Code after:
	sc := internal.ParseServiceConfig.(func(string) *serviceconfig.ParseResult)(json)
	mr.InitialState(resolver.State{
		Endpoints: []resolver.Endpoint{
			{Addresses: []resolver.Address{{Addr: backend1.Address}}},
			{Addresses: []resolver.Address{{Addr: backend2.Address}}},
		},
		ServiceConfig: sc,
	})

	dOpts := []grpc.DialOption{
		grpc.WithResolvers(mr), grpc.WithTransportCredentials(insecure.NewCredentials()),
		// Use a large backoff delay to avoid the error picker being updated
		// too quickly.
		grpc.WithConnectParams(grpc.ConnectParams{
			Backoff: backoff.Config{
				BaseDelay:  2 * defaultTestTimeout,
				Multiplier: float64(0),
				Jitter:     float64(0),
				MaxDelay:   2 * defaultTestTimeout,
			},
		}),
	}
	cc, err := grpc.NewClient(mr.Scheme()+":///", dOpts...)
	if err != nil {
		t.Fatalf("Failed to create new client: %v", err)
	}
	defer cc.Close()
	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
	defer cancel()
	client := testgrpc.NewTestServiceClient(cc)
	// Assert a round robin distribution between the two spun up backends. This
	// requires a poll and eventual consistency as both endpoint children do not
	// start in state READY.
	if err = roundrobin.CheckRoundRobinRPCs(ctx, client, []resolver.Address{{Addr: backend1.Address}, {Addr: backend2.Address}}); err != nil {
		t.Fatalf("error in expected round robin: %v", err)
	}

	// Stopping both the backends should make the channel enter
	// TransientFailure.
	backend1.Stop()
	backend2.Stop()
	testutils.AwaitState(ctx, t, cc, connectivity.TransientFailure)

	// When the resolver reports an error, the picker should get updated to
	// return the resolver error.
	mr.CC().ReportError(errors.New("test error"))
	testutils.AwaitState(ctx, t, cc, connectivity.TransientFailure)
	for ; ctx.Err() == nil; <-time.After(time.Millisecond) {
		_, err := client.EmptyCall(ctx, &testpb.Empty{})
		if err == nil {
			t.Fatalf("EmptyCall succeeded when expected to fail with %q", "test error")