Skip to content

Commit c20fba0

Browse files
xds: Exported buildXDSClientConfig to use in external packages and update xds_fake_transport.go. (grpc#9014)
This PR contains changes required for the xDS client resource parsing fuzzer. These changes facilitate the initialization of the xDS client in the fuzzer and resolve potential deadlocks during stream operations in the fake transport. ## Changes `internal/xds/xdsclient` - **Export `BuildXDSClientConfig`**: Exported `buildXDSClientConfig` to allow external packages (like the fuzzer) to construct `xdsclient.Config` from a bootstrap config. `internal/xds/clients/internal/testutils/faketransport` - **Add Timeout to `Send`**: Added a 10ms timeout to `Send` in `xds_fake_transport.go`. This prevents the client from deadlocking when sending messages if the fuzzer's server handle is not actively consuming them. RELEASE NOTES: N/A
1 parent 6477252 commit c20fba0

File tree

3 files changed

+15
-6
lines changed

3 files changed

+15
-6
lines changed

internal/xds/clients/internal/testutils/faketransport/xds_fake_transport.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"context"
2626
"fmt"
2727
"sync"
28+
"time"
2829

2930
"google.golang.org/grpc/internal/xds/clients"
3031
"google.golang.org/protobuf/proto"
@@ -182,9 +183,15 @@ func newStream(ctx context.Context) *stream {
182183
// Send sends the provided message on the stream. It puts the request into the
183184
// reqChan for consumption.
184185
func (s *stream) Send(data []byte) error {
186+
// A short timeout prevents the client from deadlocking if there is no
187+
// receiver on the server-side to consume the request (e.g., if the xDS
188+
// client sends an ACK after creating a stream but the server handle is
189+
// not actively receiving).
190+
ctx, cancel := context.WithTimeout(s.ctx, 10*time.Millisecond)
191+
defer cancel()
185192
select {
186-
case <-s.ctx.Done():
187-
return s.ctx.Err()
193+
case <-ctx.Done():
194+
return ctx.Err()
188195
case s.reqChan <- data:
189196
return nil
190197
}

internal/xds/xdsclient/clientimpl.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (mr *metricsReporter) ReportMetric(metric any) {
121121
}
122122

123123
func newClientImpl(config *bootstrap.Config, metricsRecorder estats.MetricsRecorder, target string, watchExpiryTimeout time.Duration) (*clientImpl, error) {
124-
gConfig, err := buildXDSClientConfig(config, metricsRecorder, target, watchExpiryTimeout)
124+
gConfig, err := BuildXDSClientConfig(config, metricsRecorder, target, watchExpiryTimeout)
125125
if err != nil {
126126
return nil, err
127127
}
@@ -188,8 +188,10 @@ func buildServerConfigs(bootstrapSC []*bootstrap.ServerConfig, grpcTransportConf
188188
return gServerCfg, nil
189189
}
190190

191-
// buildXDSClientConfig builds the xdsclient.Config from the bootstrap.Config.
192-
func buildXDSClientConfig(config *bootstrap.Config, metricsRecorder estats.MetricsRecorder, target string, watchExpiryTimeout time.Duration) (xdsclient.Config, error) {
191+
// BuildXDSClientConfig builds the xdsclient.Config from the bootstrap.Config.
192+
//
193+
// This function is exported for fuzz testing purposes only.
194+
func BuildXDSClientConfig(config *bootstrap.Config, metricsRecorder estats.MetricsRecorder, target string, watchExpiryTimeout time.Duration) (xdsclient.Config, error) {
193195
grpcTransportConfigs := make(map[string]grpctransport.Config)
194196
gServerCfgMap := make(map[xdsclient.ServerConfig]*bootstrap.ServerConfig)
195197

internal/xds/xdsclient/clientimpl_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ func (s) TestBuildXDSClientConfig_Success(t *testing.T) {
281281
if err != nil {
282282
t.Fatalf("Failed to create bootstrap config: %v", err)
283283
}
284-
gotCfg, err := buildXDSClientConfig(bootstrapConfig, stats.NewTestMetricsRecorder(), testTargetName, 0)
284+
gotCfg, err := BuildXDSClientConfig(bootstrapConfig, stats.NewTestMetricsRecorder(), testTargetName, 0)
285285
if err != nil {
286286
t.Fatalf("Failed to build XDSClientConfig: %v", err)
287287
}

0 commit comments

Comments
 (0)