229 lines
9.1 KiB
C#
229 lines
9.1 KiB
C#
// <copyright file="ActivitySourceAdapterTest.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.Diagnostics;
|
|
using OpenTelemetry.Resources;
|
|
using OpenTelemetry.Tests.Shared;
|
|
using Xunit;
|
|
|
|
namespace OpenTelemetry.Trace.Tests
|
|
{
|
|
public class ActivitySourceAdapterTest : IDisposable
|
|
{
|
|
private TestSampler testSampler;
|
|
private TestActivityProcessor testProcessor;
|
|
private Resource testResource = Resources.Resources.CreateServiceResource("test-resource");
|
|
private ActivitySourceAdapter activitySourceAdapter;
|
|
|
|
static ActivitySourceAdapterTest()
|
|
{
|
|
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
|
|
Activity.ForceDefaultIdFormat = true;
|
|
}
|
|
|
|
public ActivitySourceAdapterTest()
|
|
{
|
|
this.testSampler = new TestSampler();
|
|
this.testProcessor = new TestActivityProcessor();
|
|
this.activitySourceAdapter = new ActivitySourceAdapter(this.testSampler, this.testProcessor, this.testResource);
|
|
}
|
|
|
|
[Fact]
|
|
public void ActivitySourceAdapterSetsResource()
|
|
{
|
|
var activity = new Activity("test");
|
|
activity.Start();
|
|
this.activitySourceAdapter.Start(activity);
|
|
activity.Stop();
|
|
this.activitySourceAdapter.Stop(activity);
|
|
|
|
Assert.Equal(this.testResource, activity.GetResource());
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(SamplingDecision.NotRecord)]
|
|
[InlineData(SamplingDecision.Record)]
|
|
[InlineData(SamplingDecision.RecordAndSampled)]
|
|
public void ActivitySourceAdapterCallsStartStopActivityProcessor1(SamplingDecision decision)
|
|
{
|
|
this.testSampler.SamplingAction = (samplingParameters) =>
|
|
{
|
|
return new SamplingResult(decision);
|
|
};
|
|
|
|
bool startCalled = false;
|
|
bool endCalled = false;
|
|
this.testProcessor.StartAction =
|
|
(a) =>
|
|
{
|
|
startCalled = true;
|
|
|
|
// If start is called, that means activity is sampled,
|
|
// and TraceFlag is set to Recorded.
|
|
Assert.Equal(decision == SamplingDecision.Record || decision == SamplingDecision.RecordAndSampled, a.IsAllDataRequested);
|
|
Assert.Equal(decision == SamplingDecision.RecordAndSampled ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None, a.ActivityTraceFlags);
|
|
Assert.Equal(decision == SamplingDecision.RecordAndSampled, a.Recorded);
|
|
};
|
|
|
|
this.testProcessor.EndAction =
|
|
(a) =>
|
|
{
|
|
endCalled = true;
|
|
};
|
|
|
|
var activity = new Activity("test");
|
|
activity.Start();
|
|
this.activitySourceAdapter.Start(activity);
|
|
activity.Stop();
|
|
this.activitySourceAdapter.Stop(activity);
|
|
|
|
Assert.Equal(activity.IsAllDataRequested, startCalled);
|
|
Assert.Equal(activity.IsAllDataRequested, endCalled);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void ActivitySourceAdapterCallsStartStopActivityProcessor2(bool isSampled)
|
|
{
|
|
this.testSampler.SamplingAction = (samplingParameters) =>
|
|
{
|
|
return new SamplingResult(isSampled);
|
|
};
|
|
|
|
bool startCalled = false;
|
|
bool endCalled = false;
|
|
this.testProcessor.StartAction =
|
|
(a) =>
|
|
{
|
|
startCalled = true;
|
|
|
|
// If start is called, that means activity is sampled,
|
|
// and TraceFlag is set to Recorded.
|
|
Assert.Equal(isSampled, a.IsAllDataRequested);
|
|
Assert.Equal(isSampled ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None, a.ActivityTraceFlags);
|
|
Assert.Equal(isSampled, a.Recorded);
|
|
};
|
|
|
|
this.testProcessor.EndAction =
|
|
(a) =>
|
|
{
|
|
endCalled = true;
|
|
};
|
|
|
|
var activity = new Activity("test");
|
|
activity.Start();
|
|
this.activitySourceAdapter.Start(activity);
|
|
activity.Stop();
|
|
this.activitySourceAdapter.Stop(activity);
|
|
|
|
Assert.Equal(isSampled, startCalled);
|
|
Assert.Equal(isSampled, endCalled);
|
|
}
|
|
|
|
[Fact]
|
|
public void ActivitySourceAdapterPopulatesSamplingParamsCorrectlyForRootActivity()
|
|
{
|
|
this.testSampler.SamplingAction = (samplingParameters) =>
|
|
{
|
|
Assert.Equal(default, samplingParameters.ParentContext);
|
|
return new SamplingResult(SamplingDecision.RecordAndSampled);
|
|
};
|
|
|
|
// Start activity without setting parent. i.e it'll have null parent
|
|
// and becomes root activity
|
|
var activity = new Activity("test");
|
|
activity.Start();
|
|
this.activitySourceAdapter.Start(activity);
|
|
activity.Stop();
|
|
this.activitySourceAdapter.Stop(activity);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(ActivityTraceFlags.None)]
|
|
[InlineData(ActivityTraceFlags.Recorded)]
|
|
public void ActivitySourceAdapterPopulatesSamplingParamsCorrectlyForActivityWithRemoteParent(ActivityTraceFlags traceFlags)
|
|
{
|
|
var parentTraceId = ActivityTraceId.CreateRandom();
|
|
var parentSpanId = ActivitySpanId.CreateRandom();
|
|
var parentTraceFlag = (traceFlags == ActivityTraceFlags.Recorded) ? "01" : "00";
|
|
string remoteParentId = $"00-{parentTraceId}-{parentSpanId}-{parentTraceFlag}";
|
|
string tracestate = "a=b;c=d";
|
|
|
|
this.testSampler.SamplingAction = (samplingParameters) =>
|
|
{
|
|
Assert.Equal(parentTraceId, samplingParameters.ParentContext.TraceId);
|
|
Assert.Equal(parentSpanId, samplingParameters.ParentContext.SpanId);
|
|
Assert.Equal(traceFlags, samplingParameters.ParentContext.TraceFlags);
|
|
Assert.Equal(tracestate, samplingParameters.ParentContext.TraceState);
|
|
return new SamplingResult(SamplingDecision.RecordAndSampled);
|
|
};
|
|
|
|
// Create an activity with remote parent id.
|
|
// The sampling parameters are expected to be that of the
|
|
// parent context i.e the remote parent.
|
|
var activity = new Activity("test").SetParentId(remoteParentId);
|
|
activity.TraceStateString = tracestate;
|
|
activity.Start();
|
|
this.activitySourceAdapter.Start(activity);
|
|
activity.Stop();
|
|
this.activitySourceAdapter.Stop(activity);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(ActivityTraceFlags.None)]
|
|
[InlineData(ActivityTraceFlags.Recorded)]
|
|
public void ActivitySourceAdapterPopulatesSamplingParamsCorrectlyForActivityWithInProcParent(ActivityTraceFlags traceFlags)
|
|
{
|
|
// Create some parent activity.
|
|
string tracestate = "a=b;c=d";
|
|
var activityLocalParent = new Activity("testParent");
|
|
activityLocalParent.ActivityTraceFlags = traceFlags;
|
|
activityLocalParent.TraceStateString = tracestate;
|
|
activityLocalParent.Start();
|
|
|
|
this.testSampler.SamplingAction = (samplingParameters) =>
|
|
{
|
|
Assert.Equal(activityLocalParent.TraceId, samplingParameters.ParentContext.TraceId);
|
|
Assert.Equal(activityLocalParent.SpanId, samplingParameters.ParentContext.SpanId);
|
|
Assert.Equal(activityLocalParent.ActivityTraceFlags, samplingParameters.ParentContext.TraceFlags);
|
|
Assert.Equal(tracestate, samplingParameters.ParentContext.TraceState);
|
|
return new SamplingResult(SamplingDecision.RecordAndSampled);
|
|
};
|
|
|
|
// This activity will have a inproc parent.
|
|
// activity.Parent will be equal to the activity created at the beginning of this test.
|
|
// Sampling parameters are expected to be that of the parentContext.
|
|
// i.e of the parent Activity
|
|
var activity = new Activity("test");
|
|
activity.Start();
|
|
this.activitySourceAdapter.Start(activity);
|
|
activity.Stop();
|
|
this.activitySourceAdapter.Stop(activity);
|
|
|
|
activityLocalParent.Stop();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Activity.Current = null;
|
|
this.testProcessor.Dispose();
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
}
|
|
}
|