Delete BatchingSpanProcessorTest (#825)

This commit is contained in:
Cijo Thomas 2020-07-14 23:47:04 -07:00 committed by GitHub
parent 80e7bd09ec
commit a9713c8d01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 0 additions and 348 deletions

View File

@ -1,348 +0,0 @@
// <copyright file="BatchingSpanProcessorTest.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using OpenTelemetry.Testing.Export;
using OpenTelemetry.Trace.Configuration;
using OpenTelemetry.Trace.Samplers;
using Xunit;
namespace OpenTelemetry.Trace.Export.Test
{
public class BatchingSpanProcessorTest : IDisposable
{
private const string SpanName1 = "MySpanName/1";
private const string SpanName2 = "MySpanName/2";
private static readonly TimeSpan DefaultDelay = TimeSpan.FromMilliseconds(30);
private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(1);
[Fact]
public void ThrowsOnInvalidArguments()
{
Assert.Throws<ArgumentNullException>(() => new BatchingSpanProcessor(null));
Assert.Throws<ArgumentOutOfRangeException>(() => new BatchingSpanProcessor(new TestSpanExporter(null), 0, TimeSpan.FromSeconds(5), 0));
Assert.Throws<ArgumentOutOfRangeException>(() => new BatchingSpanProcessor(new TestSpanExporter(null), 2048, TimeSpan.FromSeconds(5), 0));
Assert.Throws<ArgumentOutOfRangeException>(() => new BatchingSpanProcessor(new TestSpanExporter(null), 512, TimeSpan.FromSeconds(5), 513));
}
[Fact]
public async Task ShutdownTwice()
{
using var spanProcessor = new BatchingSpanProcessor(new TestSpanExporter(null));
await spanProcessor.ShutdownAsync(CancellationToken.None);
// does not throw
await spanProcessor.ShutdownAsync(CancellationToken.None);
}
[Fact]
public async Task ShutdownWithHugeScheduleDelay()
{
using var spanProcessor =
new BatchingSpanProcessor(new TestSpanExporter(null), 128, TimeSpan.FromMinutes(1), 32);
var sw = Stopwatch.StartNew();
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(100)))
{
cts.Token.ThrowIfCancellationRequested();
await spanProcessor.ShutdownAsync(cts.Token).ConfigureAwait(false);
}
sw.Stop();
Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100));
}
[Fact]
public void ExportDifferentSampledSpans()
{
var spanExporter = new TestSpanExporter(null);
using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 128);
var span1 = this.CreateSampledEndedSpan(SpanName1, spanProcessor);
var span2 = this.CreateSampledEndedSpan(SpanName2, spanProcessor);
var exported = this.WaitForSpans(spanExporter, 2, DefaultTimeout);
Assert.Equal(2, exported.Length);
Assert.Contains(new SpanData(span1), exported);
Assert.Contains(new SpanData(span2), exported);
}
[Fact]
public void ExporterIsSlowerThanDelay()
{
var exportStartTimes = new List<long>();
var exportEndTimes = new List<long>();
var spanExporter = new TestSpanExporter(_ =>
{
exportStartTimes.Add(Stopwatch.GetTimestamp());
Thread.Sleep(50);
exportEndTimes.Add(Stopwatch.GetTimestamp());
});
using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, TimeSpan.FromMilliseconds(30), 2);
var spans = new List<SpanSdk>();
for (int i = 0; i < 20; i++)
{
spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor));
}
var exported = this.WaitForSpans(spanExporter, 20, TimeSpan.FromSeconds(2));
Assert.Equal(spans.Count, exported.Length);
Assert.InRange(exportStartTimes.Count, 10, 20);
for (int i = 1; i < exportStartTimes.Count - 1; i++)
{
Assert.InRange(exportStartTimes[i], exportEndTimes[i - 1] + 1, exportStartTimes[i + 1] - 1);
}
}
[Fact]
public void AddSpanAfterQueueIsExhausted()
{
int exportCalledCount = 0;
var spanExporter = new TestSpanExporter(_ => Interlocked.Increment(ref exportCalledCount));
using var spanProcessor = new BatchingSpanProcessor(spanExporter, 1, TimeSpan.FromMilliseconds(100), 1);
var spans = new List<SpanSdk>();
for (int i = 0; i < 20; i++)
{
spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor));
}
var exported = this.WaitForSpans(spanExporter, 1, DefaultTimeout);
Assert.Equal(1, exportCalledCount);
Assert.InRange(exported.Length, 1, 2);
Assert.Contains(new SpanData(spans.First()), exported);
}
[Fact]
public void ExportMoreSpansThanTheMaxBatchSize()
{
var exporterCalled = new ManualResetEvent(false);
int exportCalledCount = 0;
var spanExporter = new TestSpanExporter(_ =>
{
exporterCalled.Set();
Interlocked.Increment(ref exportCalledCount);
});
using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 3);
var span1 = this.CreateSampledEndedSpan(SpanName1, spanProcessor);
var span2 = this.CreateSampledEndedSpan(SpanName1, spanProcessor);
var span3 = this.CreateSampledEndedSpan(SpanName1, spanProcessor);
var span4 = this.CreateSampledEndedSpan(SpanName1, spanProcessor);
var span5 = this.CreateSampledEndedSpan(SpanName1, spanProcessor);
var span6 = this.CreateSampledEndedSpan(SpanName1, spanProcessor);
// wait for exporter to be called to stabilize tests on the build server
exporterCalled.WaitOne(TimeSpan.FromSeconds(10));
var exported = this.WaitForSpans(spanExporter, 6, DefaultTimeout);
Assert.InRange(exportCalledCount, 2, 6);
Assert.Equal(6, exported.Count());
Assert.Contains(new SpanData(span1), exported);
Assert.Contains(new SpanData(span2), exported);
Assert.Contains(new SpanData(span3), exported);
Assert.Contains(new SpanData(span4), exported);
Assert.Contains(new SpanData(span5), exported);
Assert.Contains(new SpanData(span6), exported);
}
[Fact]
public void ExportNotSampledSpans()
{
int exportCalledCount = 0;
var spanExporter = new TestSpanExporter(_ => Interlocked.Increment(ref exportCalledCount));
using var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, DefaultDelay, 3);
var span1 = this.CreateNotSampledEndedSpan(SpanName1, spanProcessor);
var span2 = this.CreateSampledEndedSpan(SpanName2, spanProcessor);
// Spans are recorded and exported in the same order as they are ended, we test that a non
// sampled span is not exported by creating and ending a sampled span after a non sampled span
// and checking that the first exported span is the sampled span (the non sampled did not get
// exported).
var exported = this.WaitForSpans(spanExporter, 1, DefaultTimeout);
Assert.Equal(1, exportCalledCount);
// Need to check this because otherwise the variable span1 is unused, other option is to not
// have a span1 variable.
Assert.Single(exported);
Assert.Contains(new SpanData(span2), exported);
}
[Fact]
public void ProcessorDoesNotBlockOnExporter()
{
var resetEvent = new ManualResetEvent(false);
var spanExporter = new TestSpanExporter(_ => resetEvent.WaitOne(TimeSpan.FromSeconds(10)));
using var factory = TracerFactory.Create(b => b
.AddProcessorPipeline(p => p
.SetExporter(spanExporter)
.SetExportingProcessor(e => new BatchingSpanProcessor(e, 128, DefaultDelay, 128))));
var tracer = factory.GetTracer(null);
var context = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded);
var span = (SpanSdk)tracer.StartSpan("foo", context);
// does not block
var sw = Stopwatch.StartNew();
span.End();
sw.Stop();
Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100));
resetEvent.Set();
var exported = this.WaitForSpans(spanExporter, 1, DefaultTimeout);
Assert.Single(exported);
}
[Fact]
public async Task ShutdownOnNotEmptyQueueFullFlush()
{
const int batchSize = 2;
int exportCalledCount = 0;
var spanExporter = new TestSpanExporter(_ => Interlocked.Increment(ref exportCalledCount));
using var spanProcessor =
new BatchingSpanProcessor(spanExporter, 128, TimeSpan.FromMilliseconds(100), batchSize);
var spans = new List<SpanSdk>();
for (int i = 0; i < 100; i++)
{
spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor));
}
Assert.True(spanExporter.ExportedSpans.Length < spans.Count);
using (var cts = new CancellationTokenSource(DefaultTimeout))
{
await spanProcessor.ShutdownAsync(cts.Token);
}
Assert.True(spanExporter.WasShutDown);
Assert.Equal(spans.Count, spanExporter.ExportedSpans.Length);
Assert.InRange(exportCalledCount, spans.Count / batchSize, spans.Count);
}
[Fact]
public async Task ShutdownOnNotEmptyQueueNotFullFlush()
{
const int batchSize = 2;
int exportCalledCount = 0;
// we'll need about 1.5 sec to export all spans
// we export 100 spans in batches of 2, each export takes 30ms, in one thread
var spanExporter = new TestSpanExporter(_ =>
{
Interlocked.Increment(ref exportCalledCount);
Thread.Sleep(30);
});
using var spanProcessor =
new BatchingSpanProcessor(spanExporter, 128, TimeSpan.FromMilliseconds(100), batchSize);
var spans = new List<SpanSdk>();
for (int i = 0; i < 100; i++)
{
spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor));
}
Assert.True(spanExporter.ExportedSpans.Length < spans.Count);
// we won't bs able to export all before cancellation will fire
using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(200)))
{
await spanProcessor.ShutdownAsync(cts.Token);
}
var exportedCount = spanExporter.ExportedSpans.Length;
Assert.True(exportedCount < spans.Count);
}
[Fact]
public void DisposeFlushes()
{
const int batchSize = 2;
int exportCalledCount = 0;
var spanExporter = new TestSpanExporter(_ => Interlocked.Increment(ref exportCalledCount));
var spans = new List<SpanSdk>();
using (var spanProcessor = new BatchingSpanProcessor(spanExporter, 128, TimeSpan.FromMilliseconds(100), batchSize))
{
for (int i = 0; i < 100; i++)
{
spans.Add(this.CreateSampledEndedSpan(i.ToString(), spanProcessor));
}
Assert.True(spanExporter.ExportedSpans.Length < spans.Count);
}
Assert.True(spanExporter.WasShutDown);
Assert.Equal(spans.Count, spanExporter.ExportedSpans.Length);
Assert.Equal(spans.Count / batchSize, exportCalledCount);
}
public void Dispose()
{
Activity.Current = null;
}
private SpanData[] WaitForSpans(TestSpanExporter exporter, int spanCount, TimeSpan timeout)
{
var sw = Stopwatch.StartNew();
while (exporter.ExportedSpans.Length < spanCount && sw.Elapsed <= timeout)
{
Thread.Sleep(10);
}
Assert.True(
exporter.ExportedSpans.Length >= spanCount,
$"Expected at least {spanCount}, got {exporter.ExportedSpans.Length}");
return exporter.ExportedSpans;
}
private SpanSdk CreateSampledEndedSpan(string spanName, SpanProcessor spanProcessor)
{
var tracer = TracerFactory.Create(b => b
.SetSampler(new AlwaysOnSampler())
.AddProcessorPipeline(p => p.AddProcessor(e => spanProcessor))
.SetTracerOptions(new TracerConfiguration())).GetTracer(null);
var context = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded);
var span = (SpanSdk)tracer.StartSpan(spanName, context);
span.End();
return span;
}
private SpanSdk CreateNotSampledEndedSpan(string spanName, SpanProcessor spanProcessor)
{
var tracer = TracerFactory.Create(b => b
.SetSampler(new AlwaysOffSampler())
.AddProcessorPipeline(p => p.AddProcessor(_ => spanProcessor))
.SetTracerOptions(new TracerConfiguration())).GetTracer(null);
var context = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None);
var span = (SpanSdk)tracer.StartSpan(spanName, context);
span.End();
return span;
}
}
}