1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-11-25 22:41:46 +02:00

Test BatchSpanProcessor export timeout directly (#1982)

Test the export timeout by waiting indefinitely for the export to
timeout instead of having a second timer, in its own goroutine, timeout.
The algorithm this replaces fails on machines that are slow and the one
meta-timer is given priority to progress over the export timer that is
being testing, resulting in a false-negative test result.

Move the testing of a BatchSpanProcessor export timeout to its own test
function. This removes the bloat this introduces to the other testing
options and allows customization that enable the testing in a
deterministic manner.
This commit is contained in:
Tyler Yahn
2021-06-09 21:05:10 +00:00
committed by GitHub
parent 7ffe28457d
commit 87cc1e1fea

View File

@@ -36,7 +36,6 @@ type testBatchExporter struct {
sizes []int sizes []int
batchCount int batchCount int
shutdownCount int shutdownCount int
delay time.Duration
errors []error errors []error
droppedCount int droppedCount int
idx int idx int
@@ -54,8 +53,6 @@ func (t *testBatchExporter) ExportSpans(ctx context.Context, spans []sdktrace.Re
return err return err
} }
time.Sleep(t.delay)
select { select {
case <-ctx.Done(): case <-ctx.Done():
t.err = ctx.Err() t.err = ctx.Err()
@@ -113,15 +110,12 @@ type testOption struct {
o []sdktrace.BatchSpanProcessorOption o []sdktrace.BatchSpanProcessorOption
wantNumSpans int wantNumSpans int
wantBatchCount int wantBatchCount int
wantExportTimeout bool
genNumSpans int genNumSpans int
delayExportBy time.Duration
parallel bool parallel bool
} }
func TestNewBatchSpanProcessorWithOptions(t *testing.T) { func TestNewBatchSpanProcessorWithOptions(t *testing.T) {
schDelay := 200 * time.Millisecond schDelay := 200 * time.Millisecond
exportTimeout := time.Millisecond
options := []testOption{ options := []testOption{
{ {
name: "default BatchSpanProcessorOptions", name: "default BatchSpanProcessorOptions",
@@ -129,15 +123,6 @@ func TestNewBatchSpanProcessorWithOptions(t *testing.T) {
wantBatchCount: 4, wantBatchCount: 4,
genNumSpans: 2053, genNumSpans: 2053,
}, },
{
name: "non-default ExportTimeout",
o: []sdktrace.BatchSpanProcessorOption{
sdktrace.WithExportTimeout(exportTimeout),
},
wantExportTimeout: true,
genNumSpans: 2053,
delayExportBy: 2 * exportTimeout, // to ensure export timeout
},
{ {
name: "non-default BatchTimeout", name: "non-default BatchTimeout",
o: []sdktrace.BatchSpanProcessorOption{ o: []sdktrace.BatchSpanProcessorOption{
@@ -204,9 +189,7 @@ func TestNewBatchSpanProcessorWithOptions(t *testing.T) {
} }
for _, option := range options { for _, option := range options {
t.Run(option.name, func(t *testing.T) { t.Run(option.name, func(t *testing.T) {
te := testBatchExporter{ te := testBatchExporter{}
delay: option.delayExportBy,
}
tp := basicTracerProvider(t) tp := basicTracerProvider(t)
ssp := createAndRegisterBatchSP(option, &te) ssp := createAndRegisterBatchSP(option, &te)
if ssp == nil { if ssp == nil {
@@ -231,15 +214,41 @@ func TestNewBatchSpanProcessorWithOptions(t *testing.T) {
gotBatchCount, option.wantBatchCount) gotBatchCount, option.wantBatchCount)
t.Errorf("Batches %v\n", te.sizes) t.Errorf("Batches %v\n", te.sizes)
} }
if option.wantExportTimeout && te.err != context.DeadlineExceeded {
t.Errorf("context deadline: got err %+v, want %+v\n",
te.err, context.DeadlineExceeded)
}
}) })
} }
} }
type stuckExporter struct {
testBatchExporter
}
// ExportSpans waits for ctx to expire and returns that error.
func (e *stuckExporter) ExportSpans(ctx context.Context, _ []sdktrace.ReadOnlySpan) error {
<-ctx.Done()
e.err = ctx.Err()
return ctx.Err()
}
func TestBatchSpanProcessorExportTimeout(t *testing.T) {
exp := new(stuckExporter)
bsp := sdktrace.NewBatchSpanProcessor(
exp,
// Set a non-zero export timeout so a deadline is set.
sdktrace.WithExportTimeout(1*time.Microsecond),
sdktrace.WithBlocking(),
)
tp := basicTracerProvider(t)
tp.RegisterSpanProcessor(bsp)
tr := tp.Tracer("BatchSpanProcessorExportTimeout")
generateSpan(t, false, tr, testOption{genNumSpans: 1})
tp.UnregisterSpanProcessor(bsp)
if exp.err != context.DeadlineExceeded {
t.Errorf("context deadline error not returned: got %+v", exp.err)
}
}
func createAndRegisterBatchSP(option testOption, te *testBatchExporter) sdktrace.SpanProcessor { func createAndRegisterBatchSP(option testOption, te *testBatchExporter) sdktrace.SpanProcessor {
// Always use blocking queue to avoid flaky tests. // Always use blocking queue to avoid flaky tests.
options := append(option.o, sdktrace.WithBlocking()) options := append(option.o, sdktrace.WithBlocking())