Repository: grpc/grpc-go
File: xds/internal/clients/xdsclient/test/helpers_test.go (Go)

Code before:
// resource.
func buildResourceName(typeName, auth, id string, ctxParams map[string]string) string {
	var typS string
	switch typeName {
	case listenerResourceTypeName:
		typS = "envoy.config.listener.v3.Listener"
	default:
		// If the name doesn't match any of the standard resources fallback
		// to the type name.
		typS = typeName
	}
	return (&xdsresource.Name{
		Scheme:        "xdstp",
		Authority:     auth,
		Type:          typS,
		ID:            id,
		ContextParams: ctxParams,
	}).String()
}

// testMetricsReporter is a MetricsReporter to be used in tests. It sends
// recording events on channels and provides helpers to check if certain events
// have taken place. It also persists metrics data keyed on the metrics
// type.
type testMetricsReporter struct {
	intCountCh *testutils.Channel

	// mu protects data.
	mu sync.Mutex
	// data is the most recent update for each metric type.
	data map[string]float64
}

// newTestMetricsReporter returns a new testMetricsReporter.
func newTestMetricsReporter() *testMetricsReporter {
	return &testMetricsReporter{
		intCountCh: testutils.NewChannelWithSize(1),

		data: make(map[string]float64),
	}
}

// metric returns the most recent data for a metric, and whether this recorder
// has received data for a metric.
func (r *testMetricsReporter) metric(name string) (float64, bool) {
	r.mu.Lock()
	defer r.mu.Unlock()
	data, ok := r.data[name]
	return data, ok
}


Review comment (suggestion):
This isn't an "int count channel".  It's a `metricsData` channel.  But see other comment about just putting the metric from the client directly on the channel.

Code after:
	var typS string
	switch typeName {
	case listenerResourceTypeName:
		typS = "envoy.config.listener.v3.Listener"
	default:
		// If the name doesn't match any of the standard resources fallback
		// to the type name.
		typS = typeName
	}
	return (&xdsresource.Name{
		Scheme:        "xdstp",
		Authority:     auth,
		Type:          typS,
		ID:            id,
		ContextParams: ctxParams,
	}).String()
}

// testMetricsReporter is a MetricsReporter to be used in tests. It sends
// recording events on channels and provides helpers to check if certain events
// have taken place.
type testMetricsReporter struct {
	metricsCh *testutils.Channel
}

// newTestMetricsReporter returns a new testMetricsReporter.
func newTestMetricsReporter() *testMetricsReporter {
	return &testMetricsReporter{
		metricsCh: testutils.NewChannelWithSize(1),
	}
}

// waitForMetric waits for a metric to be recorded and verifies that the
// recorded metrics data matches the expected metricsDataWant. Returns
// an error if failed to wait or received wrong data.
func (r *testMetricsReporter) waitForMetric(ctx context.Context, metricsDataWant any) error {
	got, err := r.metricsCh.Receive(ctx)
	if err != nil {
		return fmt.Errorf("timeout waiting for int64Count")
	}
	if diff := cmp.Diff(got, metricsDataWant); diff != "" {
		return fmt.Errorf("received unexpected metrics value (-got, +want): %v", diff)
	}
	return nil
}

// ReportMetric sends the metrics data to the metricsCh channel.
func (r *testMetricsReporter) ReportMetric(m any) {
	r.metricsCh.Send(m)
}