Repository: grpc/grpc-go
File: interop/xds_federation/client.go (Go)

Code before:
			logger.Fatalf("Unsupported credentials type: %v", c)
		}
	}
	var resetChannel bool
	switch *testCase {
	case "rpc_soak":
		resetChannel = false
	case "channel_soak":
		resetChannel = true
	default:
		logger.Fatal("Unsupported test case: ", *testCase)
	}

	// create clients as specified in flags
	var clients []clientConfig
	for i := range uris {
		var opts []grpc.DialOption
		switch creds[i] {
		case computeEngineCredsName:
			opts = append(opts, grpc.WithCredentialsBundle(google.NewComputeEngineCredentials()))
		case insecureCredsName:
			opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
		}
		cc, err := grpc.NewClient(uris[i], opts...)
		if err != nil {
			logger.Fatalf("NewClient() failed %v: %v", uris[i], err)
		}
		defer cc.Close()
		clients = append(clients, clientConfig{
			tc:   testgrpc.NewTestServiceClient(cc),
			opts: opts,
			uri:  uris[i],
		})
	}

	// run soak tests with the different clients
	logger.Infof("Clients running with test case %q", *testCase)
	var wg sync.WaitGroup
	ctx := context.Background()
	for i := range clients {
		wg.Add(1)
		go func(c clientConfig) {
			ctxWithDeadline, cancel := context.WithTimeout(ctx, time.Duration(*soakOverallTimeoutSeconds)*time.Second)
			defer cancel()
			interop.DoSoakTest(ctxWithDeadline, c.tc, c.uri, c.opts, resetChannel, *soakIterations, *soakMaxFailures, *soakRequestSize, *soakResponseSize, time.Duration(*soakPerIterationMaxAcceptableLatencyMs)*time.Millisecond, time.Duration(*soakMinTimeMsBetweenRPCs)*time.Millisecond)
			logger.Infof("%s test done for server: %s", *testCase, c.uri)
			wg.Done()
		}(clients[i])
	}
	wg.Wait()
	logger.Infoln("All clients done!")

Review comment (bug):
```suggestion
logger.Fatalf("Failed to create a client for server %q: %v", uris[i], err)
```

Code after:
	}
	for _, c := range creds {
		if c != computeEngineCredsName && c != insecureCredsName {
			logger.Fatalf("Unsupported credentials type: %v", c)
		}
	}
	var clients []clientConfig
	for i := range uris {
		var opts []grpc.DialOption
		switch creds[i] {
		case computeEngineCredsName:
			opts = append(opts, grpc.WithCredentialsBundle(google.NewComputeEngineCredentials()))
		case insecureCredsName:
			opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
		}
		cc, err := grpc.NewClient(uris[i], opts...)
		if err != nil {
			logger.Fatalf("grpc.NewClient(%q) = %v", uris[i], err)
		}
		defer cc.Close()
		clients = append(clients, clientConfig{
			conn: cc,
			tc:   testgrpc.NewTestServiceClient(cc),
			opts: opts,
			uri:  uris[i],
		})
	}

	// run soak tests with the different clients
	logger.Infof("Clients running with test case %q", *testCase)
	var wg sync.WaitGroup
	var channelForTest func() (*grpc.ClientConn, func())
	ctx := context.Background()
	for i := range clients {
		wg.Add(1)
		go func(c clientConfig) {
			ctxWithDeadline, cancel := context.WithTimeout(ctx, time.Duration(*soakOverallTimeoutSeconds)*time.Second)
			defer cancel()
			switch *testCase {
			case "rpc_soak":
				channelForTest = func() (*grpc.ClientConn, func()) { return c.conn, func() {} }
			case "channel_soak":
				channelForTest = func() (*grpc.ClientConn, func()) {
					cc, err := grpc.NewClient(c.uri, c.opts...)
					if err != nil {
						log.Fatalf("Failed to create shared channel: %v", err)
					}
					return cc, func() { cc.Close() }
				}
			default:
				logger.Fatal("Unsupported test case: ", *testCase)