diff --git a/exporters/otlp/otlptrace/otlptracegrpc/client_test.go b/exporters/otlp/otlptrace/otlptracegrpc/client_test.go index ded71a5a3b4..42e75f52972 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/client_test.go +++ b/exporters/otlp/otlptrace/otlptracegrpc/client_test.go @@ -116,8 +116,6 @@ func newGRPCExporter(t *testing.T, ctx context.Context, endpoint string, additio func newExporterEndToEndTest(t *testing.T, additionalOpts []otlptracegrpc.Option) { mc := runMockCollector(t) - <-time.After(5 * time.Millisecond) - ctx := context.Background() exp := newGRPCExporter(t, ctx, mc.endpoint, additionalOpts...) t.Cleanup(func() { @@ -248,8 +246,6 @@ func TestExportSpansTimeoutHonored(t *testing.T) { func TestNewWithMultipleAttributeTypes(t *testing.T) { mc := runMockCollector(t) - <-time.After(5 * time.Millisecond) - ctx, cancel := contextWithTimeout(context.Background(), t, 10*time.Second) t.Cleanup(cancel) @@ -384,8 +380,6 @@ func TestEmptyData(t *testing.T) { mc := runMockCollector(t) t.Cleanup(func() { require.NoError(t, mc.stop()) }) - <-time.After(5 * time.Millisecond) - ctx := context.Background() exp := newGRPCExporter(t, ctx, mc.endpoint) t.Cleanup(func() { require.NoError(t, exp.Shutdown(ctx)) }) diff --git a/exporters/otlp/otlptrace/otlptracegrpc/mock_collector_test.go b/exporters/otlp/otlptrace/otlptracegrpc/mock_collector_test.go index 56b65a5d67b..8c1ad9c9100 100644 --- a/exporters/otlp/otlptrace/otlptracegrpc/mock_collector_test.go +++ b/exporters/otlp/otlptrace/otlptracegrpc/mock_collector_test.go @@ -20,9 +20,10 @@ import ( "net" "sync" "testing" - "time" + "github.com/stretchr/testify/require" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlptracetest" @@ -38,6 +39,7 @@ func makeMockCollector(t *testing.T, mockConfig *mockConfig) *mockCollector { errors: mockConfig.errors, partial: mockConfig.partial, }, + stopped: make(chan struct{}), } } @@ -105,6 +107,7 @@ type mockCollector struct { endpoint string stopFunc func() stopOnce sync.Once + stopped chan struct{} } type mockConfig struct { @@ -118,15 +121,15 @@ var _ collectortracepb.TraceServiceServer = (*mockTraceService)(nil) var errAlreadyStopped = fmt.Errorf("already stopped") func (mc *mockCollector) stop() error { - var err = errAlreadyStopped + err := errAlreadyStopped mc.stopOnce.Do(func() { err = nil if mc.stopFunc != nil { mc.stopFunc() } }) - // Give it sometime to shutdown. - <-time.After(160 * time.Millisecond) + // Wait until gRPC server is down. + <-mc.stopped // Getting the lock ensures the traceSvc is done flushing. mc.traceSvc.mu.Lock() @@ -157,28 +160,35 @@ func (mc *mockCollector) getHeaders() metadata.MD { // runMockCollector is a helper function to create a mock Collector. func runMockCollector(t *testing.T) *mockCollector { + t.Helper() return runMockCollectorAtEndpoint(t, "localhost:0") } func runMockCollectorAtEndpoint(t *testing.T, endpoint string) *mockCollector { + t.Helper() return runMockCollectorWithConfig(t, &mockConfig{endpoint: endpoint}) } func runMockCollectorWithConfig(t *testing.T, mockConfig *mockConfig) *mockCollector { + t.Helper() ln, err := net.Listen("tcp", mockConfig.endpoint) - if err != nil { - t.Fatalf("Failed to get an endpoint: %v", err) - } + require.NoError(t, err, "net.Listen") srv := grpc.NewServer() mc := makeMockCollector(t, mockConfig) collectortracepb.RegisterTraceServiceServer(srv, mc.traceSvc) go func() { _ = srv.Serve(ln) + close(mc.stopped) }() mc.endpoint = ln.Addr().String() mc.stopFunc = srv.Stop + // Wait until gRPC server is up. + conn, err := grpc.Dial(mc.endpoint, grpc.WithBlock(), grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err, "grpc.Dial") + require.NoError(t, conn.Close(), "conn.Close") + return mc }