You've already forked opentelemetry-go
							
							
				mirror of
				https://github.com/open-telemetry/opentelemetry-go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	Fix sporadic test failure in otlp exporter http client tests (#2496)
* Fix flaky TestTimeout in otlpmetrichttp * Fix flaky TestTimeout in otlptracehttp
This commit is contained in:
		| @@ -144,15 +144,15 @@ func TestExporterShutdown(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestTimeout(t *testing.T) { | func TestTimeout(t *testing.T) { | ||||||
| 	mcCfg := mockCollectorConfig{ | 	delay := make(chan struct{}) | ||||||
| 		InjectDelay: 100 * time.Millisecond, | 	mcCfg := mockCollectorConfig{Delay: delay} | ||||||
| 	} |  | ||||||
| 	mc := runMockCollector(t, mcCfg) | 	mc := runMockCollector(t, mcCfg) | ||||||
| 	defer mc.MustStop(t) | 	defer mc.MustStop(t) | ||||||
|  | 	defer func() { close(delay) }() | ||||||
| 	client := otlpmetrichttp.NewClient( | 	client := otlpmetrichttp.NewClient( | ||||||
| 		otlpmetrichttp.WithEndpoint(mc.Endpoint()), | 		otlpmetrichttp.WithEndpoint(mc.Endpoint()), | ||||||
| 		otlpmetrichttp.WithInsecure(), | 		otlpmetrichttp.WithInsecure(), | ||||||
| 		otlpmetrichttp.WithTimeout(50*time.Millisecond), | 		otlpmetrichttp.WithTimeout(time.Nanosecond), | ||||||
| 	) | 	) | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	exporter, err := otlpmetric.New(ctx, client) | 	exporter, err := otlpmetric.New(ctx, client) | ||||||
| @@ -161,7 +161,7 @@ func TestTimeout(t *testing.T) { | |||||||
| 		assert.NoError(t, exporter.Shutdown(ctx)) | 		assert.NoError(t, exporter.Shutdown(ctx)) | ||||||
| 	}() | 	}() | ||||||
| 	err = exporter.Export(ctx, testResource, oneRecord) | 	err = exporter.Export(ctx, testResource, oneRecord) | ||||||
| 	assert.Equal(t, true, os.IsTimeout(err)) | 	assert.Equalf(t, true, os.IsTimeout(err), "expected timeout error, got: %v", err) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestEmptyData(t *testing.T) { | func TestEmptyData(t *testing.T) { | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| 	"github.com/stretchr/testify/require" | 	"github.com/stretchr/testify/require" | ||||||
| @@ -47,7 +46,7 @@ type mockCollector struct { | |||||||
|  |  | ||||||
| 	injectHTTPStatus  []int | 	injectHTTPStatus  []int | ||||||
| 	injectContentType string | 	injectContentType string | ||||||
| 	injectDelay       time.Duration | 	delay             <-chan struct{} | ||||||
|  |  | ||||||
| 	clientTLSConfig *tls.Config | 	clientTLSConfig *tls.Config | ||||||
| 	expectedHeaders map[string]string | 	expectedHeaders map[string]string | ||||||
| @@ -76,8 +75,12 @@ func (c *mockCollector) ClientTLSConfig() *tls.Config { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (c *mockCollector) serveMetrics(w http.ResponseWriter, r *http.Request) { | func (c *mockCollector) serveMetrics(w http.ResponseWriter, r *http.Request) { | ||||||
| 	if c.injectDelay != 0 { | 	if c.delay != nil { | ||||||
| 		time.Sleep(c.injectDelay) | 		select { | ||||||
|  | 		case <-c.delay: | ||||||
|  | 		case <-r.Context().Done(): | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !c.checkHeaders(r) { | 	if !c.checkHeaders(r) { | ||||||
| @@ -182,7 +185,7 @@ type mockCollectorConfig struct { | |||||||
| 	Port              int | 	Port              int | ||||||
| 	InjectHTTPStatus  []int | 	InjectHTTPStatus  []int | ||||||
| 	InjectContentType string | 	InjectContentType string | ||||||
| 	InjectDelay       time.Duration | 	Delay             <-chan struct{} | ||||||
| 	WithTLS           bool | 	WithTLS           bool | ||||||
| 	ExpectedHeaders   map[string]string | 	ExpectedHeaders   map[string]string | ||||||
| } | } | ||||||
| @@ -204,7 +207,7 @@ func runMockCollector(t *testing.T, cfg mockCollectorConfig) *mockCollector { | |||||||
| 		metricsStorage:    otlpmetrictest.NewMetricsStorage(), | 		metricsStorage:    otlpmetrictest.NewMetricsStorage(), | ||||||
| 		injectHTTPStatus:  cfg.InjectHTTPStatus, | 		injectHTTPStatus:  cfg.InjectHTTPStatus, | ||||||
| 		injectContentType: cfg.InjectContentType, | 		injectContentType: cfg.InjectContentType, | ||||||
| 		injectDelay:       cfg.InjectDelay, | 		delay:             cfg.Delay, | ||||||
| 		expectedHeaders:   cfg.ExpectedHeaders, | 		expectedHeaders:   cfg.ExpectedHeaders, | ||||||
| 	} | 	} | ||||||
| 	mux := http.NewServeMux() | 	mux := http.NewServeMux() | ||||||
|   | |||||||
| @@ -187,15 +187,15 @@ func TestExporterShutdown(t *testing.T) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestTimeout(t *testing.T) { | func TestTimeout(t *testing.T) { | ||||||
| 	mcCfg := mockCollectorConfig{ | 	delay := make(chan struct{}) | ||||||
| 		InjectDelay: 100 * time.Millisecond, | 	mcCfg := mockCollectorConfig{Delay: delay} | ||||||
| 	} |  | ||||||
| 	mc := runMockCollector(t, mcCfg) | 	mc := runMockCollector(t, mcCfg) | ||||||
| 	defer mc.MustStop(t) | 	defer mc.MustStop(t) | ||||||
|  | 	defer func() { close(delay) }() | ||||||
| 	client := otlptracehttp.NewClient( | 	client := otlptracehttp.NewClient( | ||||||
| 		otlptracehttp.WithEndpoint(mc.Endpoint()), | 		otlptracehttp.WithEndpoint(mc.Endpoint()), | ||||||
| 		otlptracehttp.WithInsecure(), | 		otlptracehttp.WithInsecure(), | ||||||
| 		otlptracehttp.WithTimeout(50*time.Millisecond), | 		otlptracehttp.WithTimeout(time.Nanosecond), | ||||||
| 	) | 	) | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	exporter, err := otlptrace.New(ctx, client) | 	exporter, err := otlptrace.New(ctx, client) | ||||||
| @@ -204,7 +204,7 @@ func TestTimeout(t *testing.T) { | |||||||
| 		assert.NoError(t, exporter.Shutdown(ctx)) | 		assert.NoError(t, exporter.Shutdown(ctx)) | ||||||
| 	}() | 	}() | ||||||
| 	err = exporter.ExportSpans(ctx, otlptracetest.SingleReadOnlySpan()) | 	err = exporter.ExportSpans(ctx, otlptracetest.SingleReadOnlySpan()) | ||||||
| 	assert.Equal(t, true, os.IsTimeout(err)) | 	assert.Equalf(t, true, os.IsTimeout(err), "expected timeout error, got: %v", err) | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestNoRetry(t *testing.T) { | func TestNoRetry(t *testing.T) { | ||||||
|   | |||||||
| @@ -26,7 +26,6 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| 	"github.com/stretchr/testify/require" | 	"github.com/stretchr/testify/require" | ||||||
| @@ -48,7 +47,7 @@ type mockCollector struct { | |||||||
| 	injectHTTPStatus     []int | 	injectHTTPStatus     []int | ||||||
| 	injectResponseHeader []map[string]string | 	injectResponseHeader []map[string]string | ||||||
| 	injectContentType    string | 	injectContentType    string | ||||||
| 	injectDelay          time.Duration | 	delay                <-chan struct{} | ||||||
|  |  | ||||||
| 	clientTLSConfig *tls.Config | 	clientTLSConfig *tls.Config | ||||||
| 	expectedHeaders map[string]string | 	expectedHeaders map[string]string | ||||||
| @@ -83,8 +82,12 @@ func (c *mockCollector) ClientTLSConfig() *tls.Config { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (c *mockCollector) serveTraces(w http.ResponseWriter, r *http.Request) { | func (c *mockCollector) serveTraces(w http.ResponseWriter, r *http.Request) { | ||||||
| 	if c.injectDelay != 0 { | 	if c.delay != nil { | ||||||
| 		time.Sleep(c.injectDelay) | 		select { | ||||||
|  | 		case <-c.delay: | ||||||
|  | 		case <-r.Context().Done(): | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !c.checkHeaders(r) { | 	if !c.checkHeaders(r) { | ||||||
| @@ -205,7 +208,7 @@ type mockCollectorConfig struct { | |||||||
| 	InjectHTTPStatus     []int | 	InjectHTTPStatus     []int | ||||||
| 	InjectContentType    string | 	InjectContentType    string | ||||||
| 	InjectResponseHeader []map[string]string | 	InjectResponseHeader []map[string]string | ||||||
| 	InjectDelay          time.Duration | 	Delay                <-chan struct{} | ||||||
| 	WithTLS              bool | 	WithTLS              bool | ||||||
| 	ExpectedHeaders      map[string]string | 	ExpectedHeaders      map[string]string | ||||||
| } | } | ||||||
| @@ -228,7 +231,7 @@ func runMockCollector(t *testing.T, cfg mockCollectorConfig) *mockCollector { | |||||||
| 		injectHTTPStatus:     cfg.InjectHTTPStatus, | 		injectHTTPStatus:     cfg.InjectHTTPStatus, | ||||||
| 		injectResponseHeader: cfg.InjectResponseHeader, | 		injectResponseHeader: cfg.InjectResponseHeader, | ||||||
| 		injectContentType:    cfg.InjectContentType, | 		injectContentType:    cfg.InjectContentType, | ||||||
| 		injectDelay:          cfg.InjectDelay, | 		delay:                cfg.Delay, | ||||||
| 		expectedHeaders:      cfg.ExpectedHeaders, | 		expectedHeaders:      cfg.ExpectedHeaders, | ||||||
| 	} | 	} | ||||||
| 	mux := http.NewServeMux() | 	mux := http.NewServeMux() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user